Loading datasets

The tasks included in this report are:

measure_labels <- read.csv('/Users/zeynepenkavi/Dropbox/PoldrackLab/SRO_Retest_Analyses/input/measure_labels.csv')

measure_labels = measure_labels %>% select(-measure_description)

measure_labels = measure_labels %>% 
  filter(ddm_task == 1)

measure_labels = measure_labels %>%
  mutate(dv = as.character(dv)) %>%
  separate(dv, c("task_group", "var"), sep = "\\.", remove=FALSE, extra = "merge")

unique(measure_labels$task_group)
 [1] "adaptive_n_back"             "attention_network_task"     
 [3] "choice_reaction_time"        "directed_forgetting"        
 [5] "dot_pattern_expectancy"      "local_global_letter"        
 [7] "motor_selective_stop_signal" "recent_probes"              
 [9] "shape_matching"              "simon"                      
[11] "stim_selective_stop_signal"  "stop_signal"                
[13] "stroop"                      "threebytwo"                 
adaptive_n_back

attention_network_task

choice_reaction_time

directed_forgetting

dot_pattern_expectancy

local_global_letter

motor_selective_stop_signal

recent_probes

shape_matching

simon

stim_selective_stop_signal

stop_signal

stroop

threebytwo

Load time 1 data

test_data <- read.csv(paste0(retest_data_path,'t1_data/variables_exhaustive.csv'))

test_data_subs = as.character(test_data$X)

test_data = test_data %>%
  select(measure_labels$dv)

test_data$sub_id = test_data_subs

rm(test_data_subs)

Load time 2 data

retest_data <- read.csv(paste0(retest_data_path,'variables_exhaustive.csv'))

retest_data_subs = as.character(retest_data$X)

retest_data = retest_data %>%
  select(measure_labels$dv)

retest_data$sub_id = retest_data_subs

retest_data = retest_data[retest_data$sub_id %in% test_data$sub_id,]

rm(retest_data_subs)

HDDM parameters in t1 data

Since HDDM parameters depend on the sample on which they are fit we also refit the model on t1 data only for the subjects that have t2 data.

hddm_refits <- read.csv(paste0(retest_data_path,'t1_data/hddm_refits_exhaustive.csv'))

test_data_hddm_fullfit <- test_data

tmp = names(test_data_hddm_fullfit)[names(test_data_hddm_fullfit) %in% names(hddm_refits) == FALSE]

hddm_refit_subs = as.character(hddm_refits$X)

hddm_refits = hddm_refits[, c(names(hddm_refits) %in% measure_labels$dv)]

hddm_refits$sub_id <- hddm_refit_subs

rm(hddm_refit_subs)

###RERAN MOTOR SS FOR REFIT (MISSING REACTIVE CONTROL HDDM DRIFT) - still missing; while missing the values from fitting to the full sample are used
# after correction this should just be sub_id
#tmp

test_data_hddm_refit = test_data_hddm_fullfit %>%
  select(tmp)

#merge hddm refits to test data
test_data_hddm_refit = merge(test_data_hddm_refit, hddm_refits, by="sub_id")

rm(test_data, hddm_refits, tmp)

Create reliability point estimates

Using hddm full sample

#for matching function to work properly assign name back to test_data
test_data  = test_data_hddm_fullfit

numeric_cols = get_numeric_cols()

#Create df of point estimate reliabilities
rel_df_cols = c('icc', 'pearson', 'var_subs', 'var_ind', 'var_resid')

rel_df = as.data.frame(matrix(ncol = length(rel_df_cols)))

names(rel_df) = rel_df_cols

for(i in 1:length(numeric_cols)){
  
  tmp = get_retest_stats(numeric_cols[i], metric = c('icc', 'pearson', 'var_breakdown'))
  
  if(i == 1){
    rel_df = tmp
  }
  else{
    rel_df = rbind(rel_df, tmp)
  }
}

row.names(rel_df) <- numeric_cols
rel_df$dv = row.names(rel_df)
row.names(rel_df) = seq(1:nrow(rel_df))

Reassign df’s and clean up

rel_df_fullfit = rel_df
rm(test_data, rel_df, tmp, i, numeric_cols, rel_df_cols)

Using hddm retest only sample

#for matching function to work properly assign name back to test_data
test_data  = test_data_hddm_refit

numeric_cols = get_numeric_cols()

#Create df of point estimate reliabilities
rel_df_cols = c('icc', 'pearson', 'var_subs', 'var_ind', 'var_resid')

rel_df = as.data.frame(matrix(ncol = length(rel_df_cols)))

names(rel_df) = rel_df_cols

for(i in 1:length(numeric_cols)){
  
  tmp = get_retest_stats(numeric_cols[i], metric = c('icc', 'pearson', 'var_breakdown'))
  
  if(i == 1){
    rel_df = tmp
  }
  else{
    rel_df = rbind(rel_df, tmp)
  }
}

row.names(rel_df) <- numeric_cols
rel_df$dv = row.names(rel_df)
row.names(rel_df) = seq(1:nrow(rel_df))

Reassign df’s and clean up

rel_df_refit = rel_df
rm(test_data, rel_df, tmp, i, numeric_cols, rel_df_cols)

Load bootstrapped reliabilities

Extract ddm vars only

Using full sample fits’ reliabilities

fullfit_boot_df <- read.csv(gzfile(paste0(retest_data_path,'bootstrap_merged.csv.gz')))
Warning in scan(file = file, what = what, sep = sep, quote = quote, dec =
dec, : embedded nul(s) found in input
fullfit_boot_df = process_boot_df(fullfit_boot_df)

fullfit_boot_df = fullfit_boot_df[fullfit_boot_df$dv %in% measure_labels$dv,]

Refits bootstrapped reliabilities

refit_boot_df = read.csv(gzfile(paste0(retest_data_path,'refits_bootstrap_merged.csv.gz')))
Warning in scan(file = file, what = what, sep = sep, quote = quote, dec =
dec, : embedded nul(s) found in input
refit_boot_df = process_boot_df(refit_boot_df)

T1 HDDM parameters

Before going on with the rest of the report first decide on whether there are significant differences in the distributions of the HDDM parameter estimates and their reliabilities depending on whether they are fit on the full sample (n=552) or retest sample (n=150) for t1 data.

Parameter stability

Differences in distributions: using scaled differences

hddm_pars_fullfit = test_data_hddm_fullfit %>%
  select(sub_id, unique(refit_boot_df$dv)) %>%
  mutate(hddm_sample = "fullfit")

hddm_pars_refit = test_data_hddm_refit %>%
  select(sub_id, unique(refit_boot_df$dv)) %>%
  mutate(hddm_sample = "refit")

hddm_pars = rbind(hddm_pars_fullfit, hddm_pars_refit)
rm(hddm_pars_fullfit, hddm_pars_refit)

hddm_pars = hddm_pars %>%
  gather(dv, value, -sub_id, -hddm_sample) %>%
  spread(hddm_sample, value) %>%
  mutate(diff = fullfit - refit) %>%
  group_by(dv) %>%
  mutate(scaled_diff = scale(diff)) %>%
  select(sub_id, dv, scaled_diff) %>%
  left_join(measure_labels[,c("dv", "rt_acc")], by = "dv") %>%
  na.omit()

hddm_pars %>%
  ggplot(aes(scaled_diff))+
  geom_density(aes(fill = dv), alpha = 0.2, color = NA)+
  geom_density(fill = "black", alpha = 1, color=NA)+
  theme(legend.position = "none")+
  xlab("Scaled difference of HDDM parameter estimate (full - refit)")

Does the distribution of scaled difference scores (between using n=150 or n=552) have a mean different than 0 allowing for random effects of parameter accounting for the different types of parameters? No.

summary(lmer(scaled_diff ~ rt_acc + (1|dv), hddm_pars))
Linear mixed model fit by REML ['lmerMod']
Formula: scaled_diff ~ rt_acc + (1 | dv)
   Data: hddm_pars

REML criterion at convergence: 25057

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-10.438  -0.501  -0.007   0.460   9.750 

Random effects:
 Groups   Name        Variance Std.Dev.
 dv       (Intercept) 1.42e-33 3.77e-17
 Residual             9.93e-01 9.97e-01
Number of obs: 8845, groups:  dv, 62

Fixed effects:
                    Estimate Std. Error t value
(Intercept)         1.90e-17   1.45e-02       0
rt_accnon-decision -3.92e-17   2.66e-02       0
rt_accthreshold     1.73e-20   2.60e-02       0

Correlation of Fixed Effects:
            (Intr) rt_cc-
rt_ccnn-dcs -0.545       
rt_ccthrshl -0.558  0.304
# Same result
# summary(MCMCglmm(scaled_diff ~ rt_acc, random = ~ dv, data=hddm_pars))

Parameter reliability

Are there differences in reliability depending which sample the HDDM parameters are estimated from? No.

hddm_rels_fullfit = rel_df_fullfit %>%
  filter(dv %in% unique(refit_boot_df$dv)) %>%
  select(dv, icc)

hddm_rels_refit = rel_df_refit %>%
  filter(dv %in% unique(refit_boot_df$dv)) %>%
  select(dv, icc) 

hddm_rels = hddm_rels_fullfit %>%
  left_join(hddm_rels_refit, by = "dv") %>%
  rename(fullfit = icc.x, refit = icc.y) %>%
  left_join(measure_labels[,c("dv", "rt_acc")], by = "dv")

rm(hddm_rels_fullfit, hddm_rels_refit)

hddm_rels %>%
  ggplot(aes(fullfit, refit, col=rt_acc))+
  geom_point()+
  geom_abline(slope=1, intercept = 0)+
  xlab("Reliability of HDDM params using n=552")+
  ylab("Reliability of HDDM params using n=150")+
  theme(legend.title = element_blank())

hddm_rels = hddm_rels %>%
  gather(sample, value, -dv, -rt_acc)

summary(lmer(value ~ sample*rt_acc + (1|dv), hddm_rels))
Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl = control
$checkConv, : Model failed to converge with max|grad| = 0.127809 (tol =
0.002, component 1)
Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl = control$checkConv, : Model is nearly unidentifiable: very large eigenvalue
 - Rescale variables?
Linear mixed model fit by REML ['lmerMod']
Formula: value ~ sample * rt_acc + (1 | dv)
   Data: hddm_rels

REML criterion at convergence: -1890

Scaled residuals: 
      Min        1Q    Median        3Q       Max 
-4.55e-07 -3.43e-08  4.37e-08  9.14e-08  2.42e-07 

Random effects:
 Groups   Name        Variance Std.Dev.
 dv       (Intercept) 1.98e-02 1.41e-01
 Residual             7.80e-16 2.79e-08
Number of obs: 124, groups:  dv, 62

Fixed effects:
                                Estimate Std. Error t value
(Intercept)                     4.74e-01   2.32e-02   20.41
samplerefit                    -8.61e-16   6.88e-09    0.00
rt_accnon-decision             -5.48e-02   4.42e-02   -1.24
rt_accthreshold                 1.98e-02   4.32e-02    0.46
samplerefit:rt_accnon-decision  9.88e-16   1.26e-08    0.00
samplerefit:rt_accthreshold     1.22e-15   1.23e-08    0.00

Correlation of Fixed Effects:
            (Intr) smplrf rt_cc- rt_cct smp:_-
samplerefit  0.000                            
rt_ccnn-dcs -0.525  0.000                     
rt_ccthrshl -0.538  0.000  0.283              
smplrft:r_-  0.000 -0.546  0.000  0.000       
smplrft:rt_  0.000 -0.559  0.000  0.000  0.305
convergence code: 0
Model failed to converge with max|grad| = 0.127809 (tol = 0.002, component 1)
Model is nearly unidentifiable: very large eigenvalue
 - Rescale variables?

You should compare model fits using either sample. That would tell you which estimates explain observed data better though given the lack of difference in parameter estimates I don’t expect these to differ either.

Conclusion: Going to use parameter estimates from refits to retest sample only for t1 data in the rest of this report because I think they are more comparable to the parameter estimates from t2.

Clean up

rm(hddm_pars, hddm_rels)

boot_df = fullfit_boot_df %>%
  filter(dv %in% unique(refit_boot_df$dv) == FALSE)

boot_df = rbind(boot_df, refit_boot_df)

rm(fullfit_boot_df, refit_boot_df)

rel_df = rel_df_refit

rm(rel_df_fullfit, rel_df_refit)

test_data = test_data_hddm_refit

rm(test_data_hddm_fullfit, test_data_hddm_refit)

DDM vs raw reliability overall

Data wrangling df’s containing point estimate reliabilities and bootstrapped reliabilities

rel_df = rel_df %>%
  select(dv, icc, var_subs, var_ind, var_resid) %>%
  left_join(measure_labels[,c("dv", "task_group","overall_difference","raw_fit","rt_acc")], by = "dv") %>%
  mutate(ddm_raw = ifelse(raw_fit == "raw", "raw", "ddm"),
         contrast = ifelse(overall_difference == "difference", "contrast", "non-contrast"))

boot_df = boot_df %>%
  select(dv, icc, var_subs, var_ind, var_resid) %>%
  left_join(measure_labels[,c("dv", "task_group","overall_difference","raw_fit","rt_acc")], by = "dv") %>%
  mutate(ddm_raw = ifelse(raw_fit == "raw", "raw", "ddm"),
         contrast = ifelse(overall_difference == "difference", "contrast", "non-contrast"))

Plot reliability point estimates comparing DDM measures to raw measures faceting for contrast measures.

ddm_point_plot = rel_df %>%
  mutate(rt_acc = as.character(rt_acc)) %>%
  filter(rt_acc != "other") %>%
  ggplot(aes(factor(raw_fit, levels = c("raw", "EZ", "hddm"), labels=c("Raw", "EZ-diffusion", "Hierarchical diffusion")), icc, fill=factor(rt_acc, levels = c("rt","accuracy", "drift rate", "threshold", "non-decision"), labels=c("Response Time", "Accuracy","Drift Rate", "Threshold", "Non-decision"))))+
  geom_boxplot()+
  facet_wrap(~factor(contrast, levels=c("non-contrast", "contrast"), labels=c("Non-contrast", "Contrast")))+
  ylab("ICC")+
  xlab("")+
  theme(legend.title = element_blank(),
        legend.position = 'bottom')+
  guides(fill = guide_legend(ncol = 2, byrow=F))

mylegend<-g_legend(ddm_point_plot)

grob_name <- names(mylegend$grobs)[1]

#manually fix the legend
#move non-decision down
#key
mylegend$grobs[grob_name][[1]]$layout[11,c(1:4)] <- c(4,8,4,8)
mylegend$grobs[grob_name][[1]]$layout[12,c(1:4)] <- c(4,8,4,8)
#text
mylegend$grobs[grob_name][[1]]$layout[17,c(1:4)] <- c(4,10,4,10)
#move threshold down
#key
mylegend$grobs[grob_name][[1]]$layout[9,c(1:4)] <- c(3,8,3,8)
mylegend$grobs[grob_name][[1]]$layout[10,c(1:4)] <- c(3,8,3,8)
#text
mylegend$grobs[grob_name][[1]]$layout[16,c(1:4)] <- c(3,10,3,10)
#move drift rate right and up
#key
mylegend$grobs[grob_name][[1]]$layout[7,c(1:4)] <- c(2,8,2,8)
mylegend$grobs[grob_name][[1]]$layout[8,c(1:4)] <- c(2,8,2,8)
#text
mylegend$grobs[grob_name][[1]]$layout[15,c(1:4)] <- c(2,10,2,10)

grid.arrange(ddm_point_plot +theme(legend.position="none"),
             mylegend, nrow=2, heights=c(10, 1))

rm(mylegend, ddm_point_plot)

Plot averaged bootstrapped reliability estimates per measure comparing DDM measures to raw measures faceting for contrast measures.

ddm_boot_plot = boot_df %>%
  group_by(dv) %>%
  summarise(mean_icc = mean(icc),
            rt_acc = unique(rt_acc),
            overall_difference = unique(overall_difference),
            raw_fit = unique(raw_fit),
            contrast = unique(contrast)) %>%
  mutate(rt_acc = as.character(rt_acc)) %>%
  filter(rt_acc != "other") %>%
  ggplot(aes(factor(raw_fit, levels = c("raw", "EZ", "hddm"), labels=c("Raw", "EZ-diffusion", "Hierarchical diffusion")), mean_icc, fill=factor(rt_acc, levels = c("rt","accuracy", "drift rate", "threshold", "non-decision"), labels=c("Response Time", "Accuracy","Drift Rate", "Threshold", "Non-decision"))))+
  geom_boxplot()+
  facet_wrap(~factor(contrast, levels=c("non-contrast", "contrast"), labels=c("Non-contrast", "Contrast")))+
  ylab("ICC")+
  xlab("")+
  theme(legend.title = element_blank(),
        legend.position = 'bottom')+
  guides(fill = guide_legend(ncol = 2, byrow=F))

mylegend<-g_legend(ddm_boot_plot)

grob_name <- names(mylegend$grobs)[1]

#manually fix the legend
#move non-decision down
#key
mylegend$grobs[grob_name][[1]]$layout[11,c(1:4)] <- c(4,8,4,8)
mylegend$grobs[grob_name][[1]]$layout[12,c(1:4)] <- c(4,8,4,8)
#text
mylegend$grobs[grob_name][[1]]$layout[17,c(1:4)] <- c(4,10,4,10)
#move threshold down
#key
mylegend$grobs[grob_name][[1]]$layout[9,c(1:4)] <- c(3,8,3,8)
mylegend$grobs[grob_name][[1]]$layout[10,c(1:4)] <- c(3,8,3,8)
#text
mylegend$grobs[grob_name][[1]]$layout[16,c(1:4)] <- c(3,10,3,10)
#move drift rate right and up
#key
mylegend$grobs[grob_name][[1]]$layout[7,c(1:4)] <- c(2,8,2,8)
mylegend$grobs[grob_name][[1]]$layout[8,c(1:4)] <- c(2,8,2,8)
#text
mylegend$grobs[grob_name][[1]]$layout[15,c(1:4)] <- c(2,10,2,10)

grid.arrange(ddm_boot_plot +theme(legend.position="none"),
             mylegend, nrow=2, heights=c(10, 1))

rm(mylegend, ddm_boot_plot)

Model testing if the reliability of raw measures differs from that of ddm estimates and if contrast measures differ from non-contrast measures.

Checking if both fixed effects of raw vs ddm and contrast vs non-contrast as well as their interaction is necessary.

Conclusion: Model with fixed effect just for contrast and not for raw vs ddm and no interaction is the best. But to answer the question on lack of difference for ddm vs raw I’ll look at the model with both fixed effects for now.

mer1 = lmer(icc ~ ddm_raw + (1|dv), boot_df %>% filter(rt_acc != "other"))
mer1a = lmer(icc ~ contrast + (1|dv), boot_df %>% filter(rt_acc != "other"))
mer2 = lmer(icc ~ ddm_raw + contrast + (1|dv), boot_df %>% filter(rt_acc != "other"))
mer3 = lmer(icc ~ ddm_raw * contrast + (1|dv), boot_df %>% filter(rt_acc != "other"))
anova(mer1, mer2, mer3)
refitting model(s) with ML (instead of REML)
anova(mer1a, mer2, mer3)
refitting model(s) with ML (instead of REML)
rm(mer1, mer3, mer1a)

Raw measures do not significantly differ from ddm parameters in their reliability but non-contrast measures are significantly more reliable compared to contrast measures.

summary(mer2)
Linear mixed model fit by REML ['lmerMod']
Formula: icc ~ ddm_raw + contrast + (1 | dv)
   Data: boot_df %>% filter(rt_acc != "other")

REML criterion at convergence: -497522

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-11.647  -0.472   0.041   0.525   6.220 

Random effects:
 Groups   Name        Variance Std.Dev.
 dv       (Intercept) 0.03484  0.1866  
 Residual             0.00901  0.0949  
Number of obs: 267000, groups:  dv, 267

Fixed effects:
                     Estimate Std. Error t value
(Intercept)            0.2359     0.0197   11.95
ddm_rawraw             0.0262     0.0233    1.12
contrastnon-contrast   0.3529     0.0234   15.07

Correlation of Fixed Effects:
            (Intr) ddm_rw
ddm_rawraw  -0.415       
cntrstnn-cn -0.654 -0.107

Best measure for each task

What is the best measure of individual difference for any measure that has both raw and DDM parameters?

Even though overall the ddm parameters are not significantly less reliable the most reliable measure is more frequently a raw measure. There are some examples of an EZ estimate being the best for a task as well. Regardless of raw vs ddm the best measure is always a non-contrast measure.

rel_df %>%
  group_by(task_group) %>%
  filter(icc == max(icc)) %>%
  select(task_group, everything())

Variance breakdown measure types

Converting variance estimates for each measure to percentage of all variance for comparability.

rel_df = rel_df %>%
  mutate(var_subs_pct = (var_subs/(var_subs+var_ind+var_resid))*100,
         var_ind_pct  = (var_ind/(var_subs+var_ind+var_resid))*100,
         var_resid_pct = (var_resid/(var_subs+var_ind+var_resid))*100)

boot_df = boot_df %>%
  mutate(var_subs_pct = (var_subs/(var_subs+var_ind+var_resid))*100,
         var_ind_pct  = (var_ind/(var_subs+var_ind+var_resid))*100,
         var_resid_pct = (var_resid/(var_subs+var_ind+var_resid))*100)
rel_df %>%
  filter(rt_acc != "other") %>%
  group_by(rt_acc, contrast, raw_fit) %>%
  summarise(mean_var_subs_pct = mean(var_subs_pct),
            mean_var_ind_pct = mean(var_ind_pct),
            mean_var_resid_pct = mean(var_resid_pct),
            sem_var_subs_pct = sem(var_subs_pct),
            sem_var_ind_pct = sem(var_ind_pct),
            sem_var_resid_pct = sem(var_resid_pct)) %>%
  ggplot(aes(factor(raw_fit, levels = c("raw", "EZ", "hddm"), labels=c("Raw", "EZ-diffusion", "Hierarchical diffusion")), mean_var_subs_pct, shape=factor(rt_acc, levels = c("rt","accuracy", "drift rate", "threshold", "non-decision"), labels=c("Response Time", "Accuracy","Drift Rate", "Threshold", "Non-decision"))))+
  geom_point(position=position_dodge(width=0.75), size = 5)+
  geom_errorbar(aes(ymin = mean_var_subs_pct - sem_var_subs_pct, ymax = mean_var_subs_pct + sem_var_subs_pct), position=position_dodge(width=0.75))+
  facet_wrap(~factor(contrast, levels=c("non-contrast", "contrast"), labels=c("Non-contrast", "Contrast")))+
  ylab("% of between subjects variance")+
  xlab("")+
  theme(legend.title = element_blank(),
        legend.position = 'bottom')

rel_df %>%
  filter(rt_acc != "other") %>%
  group_by(rt_acc, contrast, raw_fit) %>%
  summarise(mean_var_subs_pct = mean(var_subs_pct),
            mean_var_ind_pct = mean(var_ind_pct),
            mean_var_resid_pct = mean(var_resid_pct),
            sem_var_subs_pct = sem(var_subs_pct),
            sem_var_ind_pct = sem(var_ind_pct),
            sem_var_resid_pct = sem(var_resid_pct)) %>%
  ggplot(aes(factor(raw_fit, levels = c("raw", "EZ", "hddm"), labels=c("Raw", "EZ-diffusion", "Hierarchical diffusion")), mean_var_resid_pct, shape=factor(rt_acc, levels = c("rt","accuracy", "drift rate", "threshold", "non-decision"), labels=c("Response Time", "Accuracy","Drift Rate", "Threshold", "Non-decision"))))+
  geom_point(position=position_dodge(width=0.75), size = 5)+
  geom_errorbar(aes(ymin = mean_var_resid_pct - sem_var_resid_pct, ymax = mean_var_resid_pct + sem_var_resid_pct), position=position_dodge(width=0.75))+
  facet_wrap(~factor(contrast, levels=c("non-contrast", "contrast"), labels=c("Non-contrast", "Contrast")))+
  ylab("% of residual variance")+
  xlab("")+
  theme(legend.title = element_blank(),
        legend.position = 'bottom')

Model testing if the percentage of between subjects variance of raw measures differs from that of ddm estimates and if contrast measures differ from non-contrast measures.

Checking if both fixed effects of raw vs ddm and contrast vs non-contrast as well as their interaction is necessary.

Conclusion: Model with fixed effects for both is best.

mer1 = lmer(var_subs_pct ~ ddm_raw + (1|dv), boot_df %>% filter(rt_acc != "other"))
mer1a = lmer(var_subs_pct ~ contrast + (1|dv), boot_df %>% filter(rt_acc != "other"))
mer2 = lmer(var_subs_pct ~ ddm_raw + contrast + (1|dv), boot_df %>% filter(rt_acc != "other"))
mer3 = lmer(var_subs_pct ~ ddm_raw * contrast + (1|dv), boot_df %>% filter(rt_acc != "other"))
anova(mer1, mer2, mer3)
refitting model(s) with ML (instead of REML)
anova(mer1a, mer2, mer3)
refitting model(s) with ML (instead of REML)
rm(mer1, mer1a, mer3)

Raw and non-contrast measures have higher between subjects variance (ie are better individual difference measures)

summary(mer2)
Linear mixed model fit by REML ['lmerMod']
Formula: var_subs_pct ~ ddm_raw + contrast + (1 | dv)
   Data: boot_df %>% filter(rt_acc != "other")

REML criterion at convergence: 2002344

Scaled residuals: 
   Min     1Q Median     3Q    Max 
-4.126 -0.659  0.076  0.674  4.702 

Random effects:
 Groups   Name        Variance Std.Dev.
 dv       (Intercept) 171      13.1    
 Residual             105      10.2    
Number of obs: 267000, groups:  dv, 267

Fixed effects:
                     Estimate Std. Error t value
(Intercept)             41.64       1.39   30.05
ddm_rawraw               4.65       1.64    2.84
contrastnon-contrast     9.54       1.64    5.81

Correlation of Fixed Effects:
            (Intr) ddm_rw
ddm_rawraw  -0.415       
cntrstnn-cn -0.654 -0.107

Model testing if the percentage of residual variance of raw measures differs from that of ddm estimates and if contrast measures differ from non-contrast measures.

Checking if both fixed effects of raw vs ddm and contrast vs non-contrast as well as their interaction is necessary.

Conclusion: Model with fixed effect just for contrast is best. And plot above already shows that contrast measures have higher residual variance.

mer1 = lmer(var_resid_pct ~ ddm_raw + (1|dv), boot_df %>% filter(rt_acc != "other"))
mer1a = lmer(var_resid_pct ~ contrast + (1|dv), boot_df %>% filter(rt_acc != "other"))
mer2 = lmer(var_resid_pct ~ ddm_raw + contrast + (1|dv), boot_df %>% filter(rt_acc != "other"))
mer3 = lmer(var_resid_pct ~ ddm_raw * contrast + (1|dv), boot_df %>% filter(rt_acc != "other"))
anova(mer1, mer2, mer3)
refitting model(s) with ML (instead of REML)
anova(mer1a, mer2, mer3)
refitting model(s) with ML (instead of REML)
rm(mer1, mer1a, mer2, mer3)

Sample size effects on reliability

Differences in DDM parameter reliability for t1 data using either n=552 or n=150 were reported above under T1 HDDM parameters. No meaningful differences exist between these two sample sizes.

But even 150 is a large sample size for psychological studies, especially forced choice reaction time tasks that are included in this report. Here we look at how the reliability for raw and ddm measures change for sample sizes that are more common in studies using these tasks (25, 50, 75, 100, 125, 150)

Note: Not refitting HDDM’s for each of these sample sizes since a. there were no differences in parameter stability for n=150 vs 552 and b. a more comprehensive comparison using non-hierarchical estimates and model fit indices will follow. [revisit this - 150 and 552 might be too large to lead to changes in parameter estimates but smaller samples that are more common in psych studies might sway estimates more]

rel_df_sample_size = read.csv(gzfile(paste0(input_path, 'rel_df_sample_size.csv.gz')))

#Check if all vars are there
# numeric_cols[which(numeric_cols %in% unique(rel_df_sample_size$dv) == FALSE)]

rel_df_sample_size = rel_df_sample_size %>%
  left_join(measure_labels[,c("dv", "task_group","overall_difference","raw_fit","rt_acc")], by = "dv") %>%
  mutate(ddm_raw = ifelse(raw_fit == "raw", "raw", "ddm"),
         contrast = ifelse(overall_difference == "difference", "contrast", "non-contrast"),
         contrast = factor(contrast, levels=c("non-contrast", "contrast")),
         var_subs_pct = (var_subs/(var_subs+var_ind+var_resid))*100,
         var_ind_pct  = (var_ind/(var_subs+var_ind+var_resid))*100,
         var_resid_pct = (var_resid/(var_subs+var_ind+var_resid))*100)
Warning: Column `dv` joining factor and character vector, coercing into
character vector
rel_df_sample_size_summary = rel_df_sample_size %>% 
  group_by(dv, sample_size, ddm_raw, contrast) %>%
  summarise(mean_icc = mean(icc),
            sem_icc = sem(icc), 
            mean_var_subs_pct = mean(var_subs_pct),
            sem_var_subs_pct = sem(var_subs_pct),
            mean_var_ind_pct = mean(var_ind_pct),
            sem_var_ind_pct = sem(var_ind_pct),
            mean_var_resid_pct = mean(var_resid_pct),
            sem_var_resid_pct = sem(var_resid_pct))

tmp = rel_df_sample_size %>% 
  group_by(sample_size) %>%
  summarise(mean_icc = mean(icc),
            sem_icc = sem(icc), 
            mean_var_subs_pct = mean(var_subs_pct),
            sem_var_subs_pct = sem(var_subs_pct),
            mean_var_ind_pct = mean(var_ind_pct),
            sem_var_ind_pct = sem(var_ind_pct),
            mean_var_resid_pct = mean(var_resid_pct),
            sem_var_resid_pct = sem(var_resid_pct))

Does the mean reliability change with sample size?

Yes. The larger the sample size the more reliable is a given measure on average. The largest increase in reliability is when shifting from 25 to 50 subjects. This is important because many studies using these measures have sample sizes <50 per group.

rel_df_sample_size_summary %>%
  ggplot(aes(sample_size, mean_icc))+
  geom_line(aes(group = dv), alpha = 0.1)+
  geom_line(data = tmp,aes(sample_size,mean_icc), color="red")+
  geom_point(data = tmp,aes(sample_size,mean_icc), color="red")+
  geom_errorbar(data = tmp,aes(ymin=mean_icc-sem_icc, ymax = mean_icc+sem_icc), color="red", width = 0.1)+
  ylab("Mean reliability of 100 samples of size n")+
  xlab("Sample size")

summary(lmer(icc ~ factor(sample_size) + (1|dv) + (1|iteration), rel_df_sample_size))
Linear mixed model fit by REML ['lmerMod']
Formula: icc ~ factor(sample_size) + (1 | dv) + (1 | iteration)
   Data: rel_df_sample_size

REML criterion at convergence: -84292

Scaled residuals: 
   Min     1Q Median     3Q    Max 
-44.35  -0.30   0.03   0.41   5.37 

Random effects:
 Groups    Name        Variance Std.Dev.
 dv        (Intercept) 0.07084  0.2661  
 iteration (Intercept) 0.00016  0.0127  
 Residual              0.03108  0.1763  
Number of obs: 136500, groups:  dv, 273; iteration, 100

Fixed effects:
                       Estimate Std. Error t value
(Intercept)             0.40877    0.01619    25.2
factor(sample_size)50   0.02702    0.00151    17.9
factor(sample_size)75   0.03640    0.00151    24.1
factor(sample_size)100  0.04131    0.00151    27.4
factor(sample_size)125  0.04358    0.00151    28.9

Correlation of Fixed Effects:
            (Intr) f(_)50 f(_)75 f(_)10
fctr(sm_)50 -0.047                     
fctr(sm_)75 -0.047  0.500              
fctr(s_)100 -0.047  0.500  0.500       
fctr(s_)125 -0.047  0.500  0.500  0.500

Does the change in reliabiliity with sample size vary by variable type?

The changes do not differ by raw vs. ddm measures. It does differ by whether the measure is a contrast measure: For contrast measures all increases in reliability with sample size are larger than the increases for non-contrast measures. This implies that larger sample sizes are even more crucial for studies using contrast measures as trait-level measures.

tmp = rel_df_sample_size %>% 
  group_by(sample_size, ddm_raw, contrast) %>%
  summarise(mean_icc = mean(icc),
            sem_icc = sem(icc), 
            mean_var_subs_pct = mean(var_subs_pct),
            sem_var_subs_pct = sem(var_subs_pct),
            mean_var_ind_pct = mean(var_ind_pct),
            sem_var_ind_pct = sem(var_ind_pct),
            mean_var_resid_pct = mean(var_resid_pct),
            sem_var_resid_pct = sem(var_resid_pct))
rel_df_sample_size_summary %>%
  ggplot(aes(sample_size, mean_icc))+
  geom_line(aes(group = dv, color=ddm_raw), alpha = 0.1)+
  geom_line(data = tmp, aes(sample_size,mean_icc, color=ddm_raw))+
  geom_point(data = tmp, aes(sample_size,mean_icc, color=ddm_raw))+
  geom_errorbar(data = tmp,aes(ymin=mean_icc-sem_icc, ymax = mean_icc+sem_icc), color="red", width = 0.1)+
  facet_wrap(~contrast)+
  ylab("Mean reliability of 100 samples of size n")+
  xlab("Sample size")+
  theme(legend.title = element_blank(),
        legend.position = "bottom")

summary(lmer(icc ~ factor(sample_size) * contrast + (1|dv) + (1|iteration), rel_df_sample_size))
Linear mixed model fit by REML ['lmerMod']
Formula: icc ~ factor(sample_size) * contrast + (1 | dv) + (1 | iteration)
   Data: rel_df_sample_size

REML criterion at convergence: -84761

Scaled residuals: 
   Min     1Q Median     3Q    Max 
-44.30  -0.30   0.04   0.40   5.48 

Random effects:
 Groups    Name        Variance Std.Dev.
 dv        (Intercept) 0.03727  0.1931  
 iteration (Intercept) 0.00016  0.0127  
 Residual              0.03100  0.1761  
Number of obs: 136500, groups:  dv, 273; iteration, 100

Fixed effects:
                                        Estimate Std. Error t value
(Intercept)                              0.57368    0.01528    37.5
factor(sample_size)50                    0.01585    0.00196     8.1
factor(sample_size)75                    0.01985    0.00196    10.1
factor(sample_size)100                   0.02295    0.00196    11.7
factor(sample_size)125                   0.02346    0.00196    12.0
contrastcontrast                        -0.40560    0.02389   -17.0
factor(sample_size)50:contrastcontrast   0.02748    0.00307     9.0
factor(sample_size)75:contrastcontrast   0.04072    0.00307    13.3
factor(sample_size)100:contrastcontrast  0.04515    0.00307    14.7
factor(sample_size)125:contrastcontrast  0.04948    0.00307    16.1

Correlation of Fixed Effects:
            (Intr) fc(_)50 fc(_)75 fc(_)100 fc(_)125 cntrst f(_)50:
fctr(sm_)50 -0.064                                                 
fctr(sm_)75 -0.064  0.500                                          
fctr(s_)100 -0.064  0.500   0.500                                  
fctr(s_)125 -0.064  0.500   0.500   0.500                          
cntrstcntrs -0.635  0.041   0.041   0.041    0.041                 
fctr(s_)50:  0.041 -0.638  -0.319  -0.319   -0.319   -0.064        
fctr(s_)75:  0.041 -0.319  -0.638  -0.319   -0.319   -0.064  0.500 
fctr(_)100:  0.041 -0.319  -0.319  -0.638   -0.319   -0.064  0.500 
fctr(_)125:  0.041 -0.319  -0.319  -0.319   -0.638   -0.064  0.500 
            f(_)75: f(_)100:
fctr(sm_)50                 
fctr(sm_)75                 
fctr(s_)100                 
fctr(s_)125                 
cntrstcntrs                 
fctr(s_)50:                 
fctr(s_)75:                 
fctr(_)100:  0.500          
fctr(_)125:  0.500   0.500  

Does variability of reliability change with sample size?

Yes. Variability of reliability decreases with sample size. It does so more strongly for contrast measures.

rel_df_sample_size_summary %>%
  ggplot(aes(sample_size, sem_icc))+
  geom_line(aes(group = dv, color=ddm_raw), alpha = 0.1)+
  geom_line(data = tmp, aes(sample_size,sem_icc, color=ddm_raw))+
  geom_point(data = tmp, aes(sample_size,sem_icc, color=ddm_raw))+
  facet_wrap(~contrast)+
  ylab("Standard error of mean of reliability \n of 100 samples of size n")+
  xlab("Sample size")+
  theme(legend.title = element_blank(),
        legend.position = "bottom")

summary(lmer(sem_icc ~ factor(sample_size) * contrast + (1|dv), rel_df_sample_size_summary))
Linear mixed model fit by REML ['lmerMod']
Formula: sem_icc ~ factor(sample_size) * contrast + (1 | dv)
   Data: rel_df_sample_size_summary

REML criterion at convergence: -10328

Scaled residuals: 
   Min     1Q Median     3Q    Max 
-3.662 -0.327  0.004  0.292 11.654 

Random effects:
 Groups   Name        Variance  Std.Dev.
 dv       (Intercept) 0.0000301 0.00549 
 Residual             0.0000176 0.00419 
Number of obs: 1365, groups:  dv, 273

Fixed effects:
                                         Estimate Std. Error t value
(Intercept)                              0.020030   0.000543    36.9
factor(sample_size)50                   -0.008025   0.000466   -17.2
factor(sample_size)75                   -0.011408   0.000466   -24.5
factor(sample_size)100                  -0.013955   0.000466   -29.9
factor(sample_size)125                  -0.016135   0.000466   -34.6
contrastcontrast                         0.017341   0.000851    20.4
factor(sample_size)50:contrastcontrast  -0.007552   0.000731   -10.3
factor(sample_size)75:contrastcontrast  -0.010997   0.000731   -15.0
factor(sample_size)100:contrastcontrast -0.012866   0.000731   -17.6
factor(sample_size)125:contrastcontrast -0.014519   0.000731   -19.9

Correlation of Fixed Effects:
            (Intr) fc(_)50 fc(_)75 fc(_)100 fc(_)125 cntrst f(_)50:
fctr(sm_)50 -0.429                                                 
fctr(sm_)75 -0.429  0.500                                          
fctr(s_)100 -0.429  0.500   0.500                                  
fctr(s_)125 -0.429  0.500   0.500   0.500                          
cntrstcntrs -0.638  0.274   0.274   0.274    0.274                 
fctr(s_)50:  0.274 -0.638  -0.319  -0.319   -0.319   -0.429        
fctr(s_)75:  0.274 -0.319  -0.638  -0.319   -0.319   -0.429  0.500 
fctr(_)100:  0.274 -0.319  -0.319  -0.638   -0.319   -0.429  0.500 
fctr(_)125:  0.274 -0.319  -0.319  -0.319   -0.638   -0.429  0.500 
            f(_)75: f(_)100:
fctr(sm_)50                 
fctr(sm_)75                 
fctr(s_)100                 
fctr(s_)125                 
cntrstcntrs                 
fctr(s_)50:                 
fctr(s_)75:                 
fctr(_)100:  0.500          
fctr(_)125:  0.500   0.500  

Does between subjects variance change with sample size?

Yes. Between subjects variance decreases with sample size. This is more pronounced for non-contrast measures.

This goes against my intuitions. Looking at the change in between subjects percentage of individual measures’ there seems to be a lot of inter-measure variance (more pronounced below for within subject variance). I’m not sure if there is something in common for the measures that show increasing between subjects variability with sample size and that separates them from those that show decreasing between subjects variability with sample size (the slight majority).

rel_df_sample_size_summary %>%
  ggplot(aes(sample_size, mean_var_subs_pct))+
  geom_line(aes(group = dv, color=ddm_raw), alpha = 0.1)+
  geom_line(data = tmp, aes(sample_size,mean_var_subs_pct, color=ddm_raw))+
  geom_point(data = tmp, aes(sample_size,mean_var_subs_pct, color=ddm_raw))+
  facet_wrap(~contrast)+
  ylab("Mean percentage of \n between subjects variance \n of 100 samples of size n")+
  xlab("Sample size")+
  theme(legend.title = element_blank(),
        legend.position = "bottom")

summary(lmer(var_subs_pct ~ factor(sample_size) * contrast + (1|dv) + (1|iteration), rel_df_sample_size))
Linear mixed model fit by REML ['lmerMod']
Formula: var_subs_pct ~ factor(sample_size) * contrast + (1 | dv) + (1 |  
    iteration)
   Data: rel_df_sample_size

REML criterion at convergence: 1071657

Scaled residuals: 
   Min     1Q Median     3Q    Max 
-4.737 -0.672  0.055  0.682  4.888 

Random effects:
 Groups    Name        Variance Std.Dev.
 dv        (Intercept) 134.62   11.602  
 iteration (Intercept)   0.65    0.806  
 Residual              148.33   12.179  
Number of obs: 136500, groups:  dv, 273; iteration, 100

Fixed effects:
                                        Estimate Std. Error t value
(Intercept)                               58.117      0.920    63.2
factor(sample_size)50                     -2.441      0.135   -18.0
factor(sample_size)75                     -4.261      0.135   -31.5
factor(sample_size)100                    -6.056      0.135   -44.8
factor(sample_size)125                    -7.715      0.135   -57.0
contrastcontrast                         -14.339      1.437   -10.0
factor(sample_size)50:contrastcontrast     1.756      0.212     8.3
factor(sample_size)75:contrastcontrast     3.260      0.212    15.4
factor(sample_size)100:contrastcontrast    5.018      0.212    23.6
factor(sample_size)125:contrastcontrast    6.650      0.212    31.3

Correlation of Fixed Effects:
            (Intr) fc(_)50 fc(_)75 fc(_)100 fc(_)125 cntrst f(_)50:
fctr(sm_)50 -0.074                                                 
fctr(sm_)75 -0.074  0.500                                          
fctr(s_)100 -0.074  0.500   0.500                                  
fctr(s_)125 -0.074  0.500   0.500   0.500                          
cntrstcntrs -0.635  0.047   0.047   0.047    0.047                 
fctr(s_)50:  0.047 -0.638  -0.319  -0.319   -0.319   -0.074        
fctr(s_)75:  0.047 -0.319  -0.638  -0.319   -0.319   -0.074  0.500 
fctr(_)100:  0.047 -0.319  -0.319  -0.638   -0.319   -0.074  0.500 
fctr(_)125:  0.047 -0.319  -0.319  -0.319   -0.638   -0.074  0.500 
            f(_)75: f(_)100:
fctr(sm_)50                 
fctr(sm_)75                 
fctr(s_)100                 
fctr(s_)125                 
cntrstcntrs                 
fctr(s_)50:                 
fctr(s_)75:                 
fctr(_)100:  0.500          
fctr(_)125:  0.500   0.500  

Does within subjects variance change with sample size?

Yes. This again goes against my intuition but here the inter-meausre differences are even more pronounced. There appears to be some measures for which the change in two measurements at different time points is larger the more subjects are tested and those that show a smaller decrease in within subject variance with larger sample sizes. I still don’t know if these two types of measures have anything that distinguishes them.

rel_df_sample_size_summary %>%
  ggplot(aes(sample_size, mean_var_ind_pct))+
  geom_line(aes(group = dv, color=ddm_raw), alpha = 0.1)+
  geom_line(data = tmp, aes(sample_size,mean_var_ind_pct, color=ddm_raw))+
  geom_point(data = tmp, aes(sample_size,mean_var_ind_pct, color=ddm_raw))+
  facet_wrap(~contrast)+
  ylab("Mean percentage of \n within subjects variance \n of 100 samples of size n")+
  xlab("Sample size")+
  theme(legend.title = element_blank(),
        legend.position = "bottom")

summary(lmer(var_ind_pct ~ factor(sample_size) * contrast + (1|dv) + (1|iteration), rel_df_sample_size))
Linear mixed model fit by REML ['lmerMod']
Formula: var_ind_pct ~ factor(sample_size) * contrast + (1 | dv) + (1 |  
    iteration)
   Data: rel_df_sample_size

REML criterion at convergence: 1161673

Scaled residuals: 
   Min     1Q Median     3Q    Max 
-3.973 -0.718 -0.121  0.665  4.342 

Random effects:
 Groups    Name        Variance Std.Dev.
 dv        (Intercept) 217.021  14.732  
 iteration (Intercept)   0.677   0.823  
 Residual              287.045  16.942  
Number of obs: 136500, groups:  dv, 273; iteration, 100

Fixed effects:
                                        Estimate Std. Error t value
(Intercept)                               20.167      1.168    17.3
factor(sample_size)50                      3.178      0.188    16.9
factor(sample_size)75                      5.627      0.188    29.9
factor(sample_size)100                     8.057      0.188    42.8
factor(sample_size)125                    10.250      0.188    54.4
contrastcontrast                           3.862      1.827     2.1
factor(sample_size)50:contrastcontrast    -2.043      0.295    -6.9
factor(sample_size)75:contrastcontrast    -3.933      0.295   -13.3
factor(sample_size)100:contrastcontrast   -6.321      0.295   -21.4
factor(sample_size)125:contrastcontrast   -8.528      0.295   -28.9

Correlation of Fixed Effects:
            (Intr) fc(_)50 fc(_)75 fc(_)100 fc(_)125 cntrst f(_)50:
fctr(sm_)50 -0.081                                                 
fctr(sm_)75 -0.081  0.500                                          
fctr(s_)100 -0.081  0.500   0.500                                  
fctr(s_)125 -0.081  0.500   0.500   0.500                          
cntrstcntrs -0.636  0.052   0.052   0.052    0.052                 
fctr(s_)50:  0.051 -0.638  -0.319  -0.319   -0.319   -0.081        
fctr(s_)75:  0.051 -0.319  -0.638  -0.319   -0.319   -0.081  0.500 
fctr(_)100:  0.051 -0.319  -0.319  -0.638   -0.319   -0.081  0.500 
fctr(_)125:  0.051 -0.319  -0.319  -0.319   -0.638   -0.081  0.500 
            f(_)75: f(_)100:
fctr(sm_)50                 
fctr(sm_)75                 
fctr(s_)100                 
fctr(s_)125                 
cntrstcntrs                 
fctr(s_)50:                 
fctr(s_)75:                 
fctr(_)100:  0.500          
fctr(_)125:  0.500   0.500  

Does residual variance change with sample size?

rel_df_sample_size_summary %>%
  ggplot(aes(sample_size, mean_var_resid_pct))+
  geom_line(aes(group = dv, color=ddm_raw), alpha = 0.1)+
  geom_line(data = tmp, aes(sample_size,mean_var_resid_pct, color=ddm_raw))+
  geom_point(data = tmp, aes(sample_size,mean_var_resid_pct, color=ddm_raw))+
  facet_wrap(~contrast)+
  ylab("Mean percentage of residual variance \n of 100 samples of size n")+
  xlab("Sample size")+
  theme(legend.title = element_blank(),
        legend.position = "bottom")

summary(lmer(var_resid_pct ~ factor(sample_size) * contrast + (1|dv) + (1|iteration), rel_df_sample_size))
Linear mixed model fit by REML ['lmerMod']
Formula: var_resid_pct ~ factor(sample_size) * contrast + (1 | dv) + (1 |  
    iteration)
   Data: rel_df_sample_size

REML criterion at convergence: 940397

Scaled residuals: 
   Min     1Q Median     3Q    Max 
-5.248 -0.566 -0.007  0.570  6.472 

Random effects:
 Groups    Name        Variance Std.Dev.
 dv        (Intercept) 51.997   7.211   
 iteration (Intercept)  0.215   0.464   
 Residual              56.701   7.530   
Number of obs: 136500, groups:  dv, 273; iteration, 100

Fixed effects:
                                        Estimate Std. Error t value
(Intercept)                              21.7160     0.5715    38.0
factor(sample_size)50                    -0.7372     0.0837    -8.8
factor(sample_size)75                    -1.3662     0.0837   -16.3
factor(sample_size)100                   -2.0010     0.0837   -23.9
factor(sample_size)125                   -2.5352     0.0837   -30.3
contrastcontrast                         10.4776     0.8933    11.7
factor(sample_size)50:contrastcontrast    0.2869     0.1312     2.2
factor(sample_size)75:contrastcontrast    0.6733     0.1312     5.1
factor(sample_size)100:contrastcontrast   1.3024     0.1312     9.9
factor(sample_size)125:contrastcontrast   1.8779     0.1312    14.3

Correlation of Fixed Effects:
            (Intr) fc(_)50 fc(_)75 fc(_)100 fc(_)125 cntrst f(_)50:
fctr(sm_)50 -0.073                                                 
fctr(sm_)75 -0.073  0.500                                          
fctr(s_)100 -0.073  0.500   0.500                                  
fctr(s_)125 -0.073  0.500   0.500   0.500                          
cntrstcntrs -0.636  0.047   0.047   0.047    0.047                 
fctr(s_)50:  0.047 -0.638  -0.319  -0.319   -0.319   -0.073        
fctr(s_)75:  0.047 -0.319  -0.638  -0.319   -0.319   -0.073  0.500 
fctr(_)100:  0.047 -0.319  -0.319  -0.638   -0.319   -0.073  0.500 
fctr(_)125:  0.047 -0.319  -0.319  -0.319   -0.638   -0.073  0.500 
            f(_)75: f(_)100:
fctr(sm_)50                 
fctr(sm_)75                 
fctr(s_)100                 
fctr(s_)125                 
cntrstcntrs                 
fctr(s_)50:                 
fctr(s_)75:                 
fctr(_)100:  0.500          
fctr(_)125:  0.500   0.500  

Hierarchical estimation consequences

  • Is the H in HDDM important? (h vs flat) – Change in parameter value? – Change in parameter reliability?

Clustering

– Do DDM parameters capture similar processes as the raw measures in a given task or do they capture processes that are more similar across tasks? – Are these clusters more reliable than using either the raw or the DDM measures alone?

Prediction

– Do raw or DDM measures (or factor scores) predict real world outcomes better?

To Do

Prof. Domingue recommended readings: file:///Users/zeynepenkavi/Downloads/10.1007%252Fs11336-006-1478-z.pdf A HIERARCHICAL FRAMEWORK FOR MODELING SPEED AND ACCURACY ON TEST ITEMS

file:///Users/zeynepenkavi/Downloads/v66i04.pdf Fitting Diffusion Item Response Theory Models for Responses and Response Times Using the R Package diffIRT

LS0tCnRpdGxlOiAnU2VsZiBSZWd1bGF0aW9uIE9udG9sb2d5IERETSBBbmFseXNlcycKb3V0cHV0OgpnaXRodWJfZG9jdW1lbnQ6CnRvYzogeWVzCnRvY19mbG9hdDogeWVzCi0tLQoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CnNvdXJjZSgnL1VzZXJzL3pleW5lcGVua2F2aS9Ecm9wYm94L1BvbGRyYWNrTGFiL1NST19ERE1fQW5hbHlzZXMvY29kZS9TUk9fRERNX0FuYWx5c2VzX0hlbHBlcl9GdW5jdGlvbnMuUicpCgp0ZXN0X2RhdGFfcGF0aCA9ICcvVXNlcnMvemV5bmVwZW5rYXZpL0RvY3VtZW50cy9Qb2xkcmFja0xhYkxvY2FsL1NlbGZfUmVndWxhdGlvbl9PbnRvbG9neS9EYXRhL0NvbXBsZXRlXzAzLTI5LTIwMTgvJwoKcmV0ZXN0X2RhdGFfcGF0aCA9ICcvVXNlcnMvemV5bmVwZW5rYXZpL0RvY3VtZW50cy9Qb2xkcmFja0xhYkxvY2FsL1NlbGZfUmVndWxhdGlvbl9PbnRvbG9neS9EYXRhL1JldGVzdF8wMy0yOS0yMDE4LycKCmlucHV0X3BhdGggPSAnL1VzZXJzL3pleW5lcGVua2F2aS9Ecm9wYm94L1BvbGRyYWNrTGFiL1NST19ERE1fQW5hbHlzZXMvaW5wdXQvJwpgYGAKCiMjIExvYWRpbmcgZGF0YXNldHMKClRoZSB0YXNrcyBpbmNsdWRlZCBpbiB0aGlzIHJlcG9ydCBhcmU6ICAKCmBgYHtyfQptZWFzdXJlX2xhYmVscyA8LSByZWFkLmNzdignL1VzZXJzL3pleW5lcGVua2F2aS9Ecm9wYm94L1BvbGRyYWNrTGFiL1NST19SZXRlc3RfQW5hbHlzZXMvaW5wdXQvbWVhc3VyZV9sYWJlbHMuY3N2JykKCm1lYXN1cmVfbGFiZWxzID0gbWVhc3VyZV9sYWJlbHMgJT4lIHNlbGVjdCgtbWVhc3VyZV9kZXNjcmlwdGlvbikKCm1lYXN1cmVfbGFiZWxzID0gbWVhc3VyZV9sYWJlbHMgJT4lIAogIGZpbHRlcihkZG1fdGFzayA9PSAxKQoKbWVhc3VyZV9sYWJlbHMgPSBtZWFzdXJlX2xhYmVscyAlPiUKICBtdXRhdGUoZHYgPSBhcy5jaGFyYWN0ZXIoZHYpKSAlPiUKICBzZXBhcmF0ZShkdiwgYygidGFza19ncm91cCIsICJ2YXIiKSwgc2VwID0gIlxcLiIsIHJlbW92ZT1GQUxTRSwgZXh0cmEgPSAibWVyZ2UiKQoKdW5pcXVlKG1lYXN1cmVfbGFiZWxzJHRhc2tfZ3JvdXApCmBgYAoKIyMjIExvYWQgdGltZSAxIGRhdGEKYGBge3J9CnRlc3RfZGF0YSA8LSByZWFkLmNzdihwYXN0ZTAocmV0ZXN0X2RhdGFfcGF0aCwndDFfZGF0YS92YXJpYWJsZXNfZXhoYXVzdGl2ZS5jc3YnKSkKCnRlc3RfZGF0YV9zdWJzID0gYXMuY2hhcmFjdGVyKHRlc3RfZGF0YSRYKQoKdGVzdF9kYXRhID0gdGVzdF9kYXRhICU+JQogIHNlbGVjdChtZWFzdXJlX2xhYmVscyRkdikKCnRlc3RfZGF0YSRzdWJfaWQgPSB0ZXN0X2RhdGFfc3VicwoKcm0odGVzdF9kYXRhX3N1YnMpCmBgYAoKIyMjIExvYWQgdGltZSAyIGRhdGEgCmBgYHtyfQpyZXRlc3RfZGF0YSA8LSByZWFkLmNzdihwYXN0ZTAocmV0ZXN0X2RhdGFfcGF0aCwndmFyaWFibGVzX2V4aGF1c3RpdmUuY3N2JykpCgpyZXRlc3RfZGF0YV9zdWJzID0gYXMuY2hhcmFjdGVyKHJldGVzdF9kYXRhJFgpCgpyZXRlc3RfZGF0YSA9IHJldGVzdF9kYXRhICU+JQogIHNlbGVjdChtZWFzdXJlX2xhYmVscyRkdikKCnJldGVzdF9kYXRhJHN1Yl9pZCA9IHJldGVzdF9kYXRhX3N1YnMKCnJldGVzdF9kYXRhID0gcmV0ZXN0X2RhdGFbcmV0ZXN0X2RhdGEkc3ViX2lkICVpbiUgdGVzdF9kYXRhJHN1Yl9pZCxdCgpybShyZXRlc3RfZGF0YV9zdWJzKQpgYGAKCiMjIyBIRERNIHBhcmFtZXRlcnMgaW4gdDEgZGF0YQoKU2luY2UgSERETSBwYXJhbWV0ZXJzIGRlcGVuZCBvbiB0aGUgc2FtcGxlIG9uIHdoaWNoIHRoZXkgYXJlIGZpdCB3ZSBhbHNvIHJlZml0IHRoZSBtb2RlbCBvbiB0MSBkYXRhIG9ubHkgZm9yIHRoZSBzdWJqZWN0cyB0aGF0IGhhdmUgdDIgZGF0YS4KCmBgYHtyfQpoZGRtX3JlZml0cyA8LSByZWFkLmNzdihwYXN0ZTAocmV0ZXN0X2RhdGFfcGF0aCwndDFfZGF0YS9oZGRtX3JlZml0c19leGhhdXN0aXZlLmNzdicpKQoKdGVzdF9kYXRhX2hkZG1fZnVsbGZpdCA8LSB0ZXN0X2RhdGEKCnRtcCA9IG5hbWVzKHRlc3RfZGF0YV9oZGRtX2Z1bGxmaXQpW25hbWVzKHRlc3RfZGF0YV9oZGRtX2Z1bGxmaXQpICVpbiUgbmFtZXMoaGRkbV9yZWZpdHMpID09IEZBTFNFXQoKaGRkbV9yZWZpdF9zdWJzID0gYXMuY2hhcmFjdGVyKGhkZG1fcmVmaXRzJFgpCgpoZGRtX3JlZml0cyA9IGhkZG1fcmVmaXRzWywgYyhuYW1lcyhoZGRtX3JlZml0cykgJWluJSBtZWFzdXJlX2xhYmVscyRkdildCgpoZGRtX3JlZml0cyRzdWJfaWQgPC0gaGRkbV9yZWZpdF9zdWJzCgpybShoZGRtX3JlZml0X3N1YnMpCgojIyNSRVJBTiBNT1RPUiBTUyBGT1IgUkVGSVQgKE1JU1NJTkcgUkVBQ1RJVkUgQ09OVFJPTCBIRERNIERSSUZUKSAtIHN0aWxsIG1pc3Npbmc7IHdoaWxlIG1pc3NpbmcgdGhlIHZhbHVlcyBmcm9tIGZpdHRpbmcgdG8gdGhlIGZ1bGwgc2FtcGxlIGFyZSB1c2VkCiMgYWZ0ZXIgY29ycmVjdGlvbiB0aGlzIHNob3VsZCBqdXN0IGJlIHN1Yl9pZAojdG1wCgp0ZXN0X2RhdGFfaGRkbV9yZWZpdCA9IHRlc3RfZGF0YV9oZGRtX2Z1bGxmaXQgJT4lCiAgc2VsZWN0KHRtcCkKCiNtZXJnZSBoZGRtIHJlZml0cyB0byB0ZXN0IGRhdGEKdGVzdF9kYXRhX2hkZG1fcmVmaXQgPSBtZXJnZSh0ZXN0X2RhdGFfaGRkbV9yZWZpdCwgaGRkbV9yZWZpdHMsIGJ5PSJzdWJfaWQiKQoKcm0odGVzdF9kYXRhLCBoZGRtX3JlZml0cywgdG1wKQpgYGAKCiMjIyBDcmVhdGUgcmVsaWFiaWxpdHkgcG9pbnQgZXN0aW1hdGVzCgojIyMjIFVzaW5nIGhkZG0gZnVsbCBzYW1wbGUKCmBgYHtyfQojZm9yIG1hdGNoaW5nIGZ1bmN0aW9uIHRvIHdvcmsgcHJvcGVybHkgYXNzaWduIG5hbWUgYmFjayB0byB0ZXN0X2RhdGEKdGVzdF9kYXRhICA9IHRlc3RfZGF0YV9oZGRtX2Z1bGxmaXQKCm51bWVyaWNfY29scyA9IGdldF9udW1lcmljX2NvbHMoKQoKI0NyZWF0ZSBkZiBvZiBwb2ludCBlc3RpbWF0ZSByZWxpYWJpbGl0aWVzCnJlbF9kZl9jb2xzID0gYygnaWNjJywgJ3BlYXJzb24nLCAndmFyX3N1YnMnLCAndmFyX2luZCcsICd2YXJfcmVzaWQnKQoKcmVsX2RmID0gYXMuZGF0YS5mcmFtZShtYXRyaXgobmNvbCA9IGxlbmd0aChyZWxfZGZfY29scykpKQoKbmFtZXMocmVsX2RmKSA9IHJlbF9kZl9jb2xzCgpmb3IoaSBpbiAxOmxlbmd0aChudW1lcmljX2NvbHMpKXsKICAKICB0bXAgPSBnZXRfcmV0ZXN0X3N0YXRzKG51bWVyaWNfY29sc1tpXSwgbWV0cmljID0gYygnaWNjJywgJ3BlYXJzb24nLCAndmFyX2JyZWFrZG93bicpKQogIAogIGlmKGkgPT0gMSl7CiAgICByZWxfZGYgPSB0bXAKICB9CiAgZWxzZXsKICAgIHJlbF9kZiA9IHJiaW5kKHJlbF9kZiwgdG1wKQogIH0KfQoKcm93Lm5hbWVzKHJlbF9kZikgPC0gbnVtZXJpY19jb2xzCnJlbF9kZiRkdiA9IHJvdy5uYW1lcyhyZWxfZGYpCnJvdy5uYW1lcyhyZWxfZGYpID0gc2VxKDE6bnJvdyhyZWxfZGYpKQpgYGAKClJlYXNzaWduIGRmJ3MgYW5kIGNsZWFuIHVwCgpgYGB7cn0KcmVsX2RmX2Z1bGxmaXQgPSByZWxfZGYKcm0odGVzdF9kYXRhLCByZWxfZGYsIHRtcCwgaSwgbnVtZXJpY19jb2xzLCByZWxfZGZfY29scykKYGBgCgojIyMjIFVzaW5nIGhkZG0gcmV0ZXN0IG9ubHkgc2FtcGxlCgpgYGB7cn0KI2ZvciBtYXRjaGluZyBmdW5jdGlvbiB0byB3b3JrIHByb3Blcmx5IGFzc2lnbiBuYW1lIGJhY2sgdG8gdGVzdF9kYXRhCnRlc3RfZGF0YSAgPSB0ZXN0X2RhdGFfaGRkbV9yZWZpdAoKbnVtZXJpY19jb2xzID0gZ2V0X251bWVyaWNfY29scygpCgojQ3JlYXRlIGRmIG9mIHBvaW50IGVzdGltYXRlIHJlbGlhYmlsaXRpZXMKcmVsX2RmX2NvbHMgPSBjKCdpY2MnLCAncGVhcnNvbicsICd2YXJfc3VicycsICd2YXJfaW5kJywgJ3Zhcl9yZXNpZCcpCgpyZWxfZGYgPSBhcy5kYXRhLmZyYW1lKG1hdHJpeChuY29sID0gbGVuZ3RoKHJlbF9kZl9jb2xzKSkpCgpuYW1lcyhyZWxfZGYpID0gcmVsX2RmX2NvbHMKCmZvcihpIGluIDE6bGVuZ3RoKG51bWVyaWNfY29scykpewogIAogIHRtcCA9IGdldF9yZXRlc3Rfc3RhdHMobnVtZXJpY19jb2xzW2ldLCBtZXRyaWMgPSBjKCdpY2MnLCAncGVhcnNvbicsICd2YXJfYnJlYWtkb3duJykpCiAgCiAgaWYoaSA9PSAxKXsKICAgIHJlbF9kZiA9IHRtcAogIH0KICBlbHNlewogICAgcmVsX2RmID0gcmJpbmQocmVsX2RmLCB0bXApCiAgfQp9Cgpyb3cubmFtZXMocmVsX2RmKSA8LSBudW1lcmljX2NvbHMKcmVsX2RmJGR2ID0gcm93Lm5hbWVzKHJlbF9kZikKcm93Lm5hbWVzKHJlbF9kZikgPSBzZXEoMTpucm93KHJlbF9kZikpCmBgYAoKUmVhc3NpZ24gZGYncyBhbmQgY2xlYW4gdXAKCmBgYHtyfQpyZWxfZGZfcmVmaXQgPSByZWxfZGYKcm0odGVzdF9kYXRhLCByZWxfZGYsIHRtcCwgaSwgbnVtZXJpY19jb2xzLCByZWxfZGZfY29scykKYGBgCgojIyMgTG9hZCBib290c3RyYXBwZWQgcmVsaWFiaWxpdGllcwoKRXh0cmFjdCBkZG0gdmFycyBvbmx5ICAKClVzaW5nIGZ1bGwgc2FtcGxlIGZpdHMnIHJlbGlhYmlsaXRpZXMgIAoKYGBge3J9CmZ1bGxmaXRfYm9vdF9kZiA8LSByZWFkLmNzdihnemZpbGUocGFzdGUwKHJldGVzdF9kYXRhX3BhdGgsJ2Jvb3RzdHJhcF9tZXJnZWQuY3N2Lmd6JykpKQoKZnVsbGZpdF9ib290X2RmID0gcHJvY2Vzc19ib290X2RmKGZ1bGxmaXRfYm9vdF9kZikKCmZ1bGxmaXRfYm9vdF9kZiA9IGZ1bGxmaXRfYm9vdF9kZltmdWxsZml0X2Jvb3RfZGYkZHYgJWluJSBtZWFzdXJlX2xhYmVscyRkdixdCmBgYAoKUmVmaXRzIGJvb3RzdHJhcHBlZCByZWxpYWJpbGl0aWVzICAKCmBgYHtyfQpyZWZpdF9ib290X2RmID0gcmVhZC5jc3YoZ3pmaWxlKHBhc3RlMChyZXRlc3RfZGF0YV9wYXRoLCdyZWZpdHNfYm9vdHN0cmFwX21lcmdlZC5jc3YuZ3onKSkpCgpyZWZpdF9ib290X2RmID0gcHJvY2Vzc19ib290X2RmKHJlZml0X2Jvb3RfZGYpCmBgYAoKIyMgVDEgSERETSBwYXJhbWV0ZXJzCgpCZWZvcmUgZ29pbmcgb24gd2l0aCB0aGUgcmVzdCBvZiB0aGUgcmVwb3J0IGZpcnN0IGRlY2lkZSBvbiB3aGV0aGVyIHRoZXJlIGFyZSBzaWduaWZpY2FudCBkaWZmZXJlbmNlcyBpbiB0aGUgZGlzdHJpYnV0aW9ucyBvZiB0aGUgSERETSBwYXJhbWV0ZXIgZXN0aW1hdGVzIGFuZCB0aGVpciByZWxpYWJpbGl0aWVzIGRlcGVuZGluZyBvbiB3aGV0aGVyIHRoZXkgYXJlIGZpdCBvbiB0aGUgZnVsbCBzYW1wbGUgKG49NTUyKSBvciByZXRlc3Qgc2FtcGxlIChuPTE1MCkgZm9yIHQxIGRhdGEuICAKCiMjIyBQYXJhbWV0ZXIgc3RhYmlsaXR5CgpEaWZmZXJlbmNlcyBpbiBkaXN0cmlidXRpb25zOiB1c2luZyBzY2FsZWQgZGlmZmVyZW5jZXMKCmBgYHtyfQpoZGRtX3BhcnNfZnVsbGZpdCA9IHRlc3RfZGF0YV9oZGRtX2Z1bGxmaXQgJT4lCiAgc2VsZWN0KHN1Yl9pZCwgdW5pcXVlKHJlZml0X2Jvb3RfZGYkZHYpKSAlPiUKICBtdXRhdGUoaGRkbV9zYW1wbGUgPSAiZnVsbGZpdCIpCgpoZGRtX3BhcnNfcmVmaXQgPSB0ZXN0X2RhdGFfaGRkbV9yZWZpdCAlPiUKICBzZWxlY3Qoc3ViX2lkLCB1bmlxdWUocmVmaXRfYm9vdF9kZiRkdikpICU+JQogIG11dGF0ZShoZGRtX3NhbXBsZSA9ICJyZWZpdCIpCgpoZGRtX3BhcnMgPSByYmluZChoZGRtX3BhcnNfZnVsbGZpdCwgaGRkbV9wYXJzX3JlZml0KQpybShoZGRtX3BhcnNfZnVsbGZpdCwgaGRkbV9wYXJzX3JlZml0KQoKaGRkbV9wYXJzID0gaGRkbV9wYXJzICU+JQogIGdhdGhlcihkdiwgdmFsdWUsIC1zdWJfaWQsIC1oZGRtX3NhbXBsZSkgJT4lCiAgc3ByZWFkKGhkZG1fc2FtcGxlLCB2YWx1ZSkgJT4lCiAgbXV0YXRlKGRpZmYgPSBmdWxsZml0IC0gcmVmaXQpICU+JQogIGdyb3VwX2J5KGR2KSAlPiUKICBtdXRhdGUoc2NhbGVkX2RpZmYgPSBzY2FsZShkaWZmKSkgJT4lCiAgc2VsZWN0KHN1Yl9pZCwgZHYsIHNjYWxlZF9kaWZmKSAlPiUKICBsZWZ0X2pvaW4obWVhc3VyZV9sYWJlbHNbLGMoImR2IiwgInJ0X2FjYyIpXSwgYnkgPSAiZHYiKSAlPiUKICBuYS5vbWl0KCkKCmhkZG1fcGFycyAlPiUKICBnZ3Bsb3QoYWVzKHNjYWxlZF9kaWZmKSkrCiAgZ2VvbV9kZW5zaXR5KGFlcyhmaWxsID0gZHYpLCBhbHBoYSA9IDAuMiwgY29sb3IgPSBOQSkrCiAgZ2VvbV9kZW5zaXR5KGZpbGwgPSAiYmxhY2siLCBhbHBoYSA9IDEsIGNvbG9yPU5BKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpKwogIHhsYWIoIlNjYWxlZCBkaWZmZXJlbmNlIG9mIEhERE0gcGFyYW1ldGVyIGVzdGltYXRlIChmdWxsIC0gcmVmaXQpIikKYGBgCgpEb2VzIHRoZSBkaXN0cmlidXRpb24gb2Ygc2NhbGVkIGRpZmZlcmVuY2Ugc2NvcmVzIChiZXR3ZWVuIHVzaW5nIG49MTUwIG9yIG49NTUyKSBoYXZlIGEgbWVhbiBkaWZmZXJlbnQgdGhhbiAwIGFsbG93aW5nIGZvciByYW5kb20gZWZmZWN0cyBvZiBwYXJhbWV0ZXIgYWNjb3VudGluZyBmb3IgdGhlIGRpZmZlcmVudCB0eXBlcyBvZiBwYXJhbWV0ZXJzPyBOby4KCmBgYHtyfQpzdW1tYXJ5KGxtZXIoc2NhbGVkX2RpZmYgfiBydF9hY2MgKyAoMXxkdiksIGhkZG1fcGFycykpCiMgU2FtZSByZXN1bHQKIyBzdW1tYXJ5KE1DTUNnbG1tKHNjYWxlZF9kaWZmIH4gcnRfYWNjLCByYW5kb20gPSB+IGR2LCBkYXRhPWhkZG1fcGFycykpCmBgYAoKIyMjIFBhcmFtZXRlciByZWxpYWJpbGl0eQoKQXJlIHRoZXJlIGRpZmZlcmVuY2VzIGluIHJlbGlhYmlsaXR5IGRlcGVuZGluZyB3aGljaCBzYW1wbGUgdGhlIEhERE0gcGFyYW1ldGVycyBhcmUgZXN0aW1hdGVkIGZyb20/IE5vLgoKYGBge3J9CmhkZG1fcmVsc19mdWxsZml0ID0gcmVsX2RmX2Z1bGxmaXQgJT4lCiAgZmlsdGVyKGR2ICVpbiUgdW5pcXVlKHJlZml0X2Jvb3RfZGYkZHYpKSAlPiUKICBzZWxlY3QoZHYsIGljYykKCmhkZG1fcmVsc19yZWZpdCA9IHJlbF9kZl9yZWZpdCAlPiUKICBmaWx0ZXIoZHYgJWluJSB1bmlxdWUocmVmaXRfYm9vdF9kZiRkdikpICU+JQogIHNlbGVjdChkdiwgaWNjKSAKCmhkZG1fcmVscyA9IGhkZG1fcmVsc19mdWxsZml0ICU+JQogIGxlZnRfam9pbihoZGRtX3JlbHNfcmVmaXQsIGJ5ID0gImR2IikgJT4lCiAgcmVuYW1lKGZ1bGxmaXQgPSBpY2MueCwgcmVmaXQgPSBpY2MueSkgJT4lCiAgbGVmdF9qb2luKG1lYXN1cmVfbGFiZWxzWyxjKCJkdiIsICJydF9hY2MiKV0sIGJ5ID0gImR2IikKCnJtKGhkZG1fcmVsc19mdWxsZml0LCBoZGRtX3JlbHNfcmVmaXQpCgpoZGRtX3JlbHMgJT4lCiAgZ2dwbG90KGFlcyhmdWxsZml0LCByZWZpdCwgY29sPXJ0X2FjYykpKwogIGdlb21fcG9pbnQoKSsKICBnZW9tX2FibGluZShzbG9wZT0xLCBpbnRlcmNlcHQgPSAwKSsKICB4bGFiKCJSZWxpYWJpbGl0eSBvZiBIRERNIHBhcmFtcyB1c2luZyBuPTU1MiIpKwogIHlsYWIoIlJlbGlhYmlsaXR5IG9mIEhERE0gcGFyYW1zIHVzaW5nIG49MTUwIikrCiAgdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKQpgYGAKCmBgYHtyfQpoZGRtX3JlbHMgPSBoZGRtX3JlbHMgJT4lCiAgZ2F0aGVyKHNhbXBsZSwgdmFsdWUsIC1kdiwgLXJ0X2FjYykKCnN1bW1hcnkobG1lcih2YWx1ZSB+IHNhbXBsZSpydF9hY2MgKyAoMXxkdiksIGhkZG1fcmVscykpCmBgYAoKWW91IHNob3VsZCBjb21wYXJlIG1vZGVsIGZpdHMgdXNpbmcgZWl0aGVyIHNhbXBsZS4gVGhhdCB3b3VsZCB0ZWxsIHlvdSB3aGljaCBlc3RpbWF0ZXMgZXhwbGFpbiBvYnNlcnZlZCBkYXRhIGJldHRlciB0aG91Z2ggZ2l2ZW4gdGhlIGxhY2sgb2YgZGlmZmVyZW5jZSBpbiBwYXJhbWV0ZXIgZXN0aW1hdGVzIEkgZG9uJ3QgZXhwZWN0IHRoZXNlIHRvIGRpZmZlciBlaXRoZXIuCgpDb25jbHVzaW9uOiBHb2luZyB0byB1c2UgcGFyYW1ldGVyIGVzdGltYXRlcyBmcm9tIHJlZml0cyB0byByZXRlc3Qgc2FtcGxlIG9ubHkgZm9yIHQxIGRhdGEgaW4gdGhlIHJlc3Qgb2YgdGhpcyByZXBvcnQgYmVjYXVzZSBJIHRoaW5rIHRoZXkgYXJlIG1vcmUgY29tcGFyYWJsZSB0byB0aGUgcGFyYW1ldGVyIGVzdGltYXRlcyBmcm9tIHQyLgoKQ2xlYW4gdXAKCmBgYHtyfQpybShoZGRtX3BhcnMsIGhkZG1fcmVscykKCmJvb3RfZGYgPSBmdWxsZml0X2Jvb3RfZGYgJT4lCiAgZmlsdGVyKGR2ICVpbiUgdW5pcXVlKHJlZml0X2Jvb3RfZGYkZHYpID09IEZBTFNFKQoKYm9vdF9kZiA9IHJiaW5kKGJvb3RfZGYsIHJlZml0X2Jvb3RfZGYpCgpybShmdWxsZml0X2Jvb3RfZGYsIHJlZml0X2Jvb3RfZGYpCgpyZWxfZGYgPSByZWxfZGZfcmVmaXQKCnJtKHJlbF9kZl9mdWxsZml0LCByZWxfZGZfcmVmaXQpCgp0ZXN0X2RhdGEgPSB0ZXN0X2RhdGFfaGRkbV9yZWZpdAoKcm0odGVzdF9kYXRhX2hkZG1fZnVsbGZpdCwgdGVzdF9kYXRhX2hkZG1fcmVmaXQpCmBgYAoKIyMgRERNIHZzIHJhdyByZWxpYWJpbGl0eSBvdmVyYWxsCgpEYXRhIHdyYW5nbGluZyBkZidzIGNvbnRhaW5pbmcgcG9pbnQgZXN0aW1hdGUgcmVsaWFiaWxpdGllcyBhbmQgYm9vdHN0cmFwcGVkIHJlbGlhYmlsaXRpZXMKCmBgYHtyfQpyZWxfZGYgPSByZWxfZGYgJT4lCiAgc2VsZWN0KGR2LCBpY2MsIHZhcl9zdWJzLCB2YXJfaW5kLCB2YXJfcmVzaWQpICU+JQogIGxlZnRfam9pbihtZWFzdXJlX2xhYmVsc1ssYygiZHYiLCAidGFza19ncm91cCIsIm92ZXJhbGxfZGlmZmVyZW5jZSIsInJhd19maXQiLCJydF9hY2MiKV0sIGJ5ID0gImR2IikgJT4lCiAgbXV0YXRlKGRkbV9yYXcgPSBpZmVsc2UocmF3X2ZpdCA9PSAicmF3IiwgInJhdyIsICJkZG0iKSwKICAgICAgICAgY29udHJhc3QgPSBpZmVsc2Uob3ZlcmFsbF9kaWZmZXJlbmNlID09ICJkaWZmZXJlbmNlIiwgImNvbnRyYXN0IiwgIm5vbi1jb250cmFzdCIpKQoKYm9vdF9kZiA9IGJvb3RfZGYgJT4lCiAgc2VsZWN0KGR2LCBpY2MsIHZhcl9zdWJzLCB2YXJfaW5kLCB2YXJfcmVzaWQpICU+JQogIGxlZnRfam9pbihtZWFzdXJlX2xhYmVsc1ssYygiZHYiLCAidGFza19ncm91cCIsIm92ZXJhbGxfZGlmZmVyZW5jZSIsInJhd19maXQiLCJydF9hY2MiKV0sIGJ5ID0gImR2IikgJT4lCiAgbXV0YXRlKGRkbV9yYXcgPSBpZmVsc2UocmF3X2ZpdCA9PSAicmF3IiwgInJhdyIsICJkZG0iKSwKICAgICAgICAgY29udHJhc3QgPSBpZmVsc2Uob3ZlcmFsbF9kaWZmZXJlbmNlID09ICJkaWZmZXJlbmNlIiwgImNvbnRyYXN0IiwgIm5vbi1jb250cmFzdCIpKQpgYGAKClBsb3QgcmVsaWFiaWxpdHkgcG9pbnQgZXN0aW1hdGVzIGNvbXBhcmluZyBERE0gbWVhc3VyZXMgdG8gcmF3IG1lYXN1cmVzIGZhY2V0aW5nIGZvciBjb250cmFzdCBtZWFzdXJlcy4KCmBgYHtyfQpkZG1fcG9pbnRfcGxvdCA9IHJlbF9kZiAlPiUKICBtdXRhdGUocnRfYWNjID0gYXMuY2hhcmFjdGVyKHJ0X2FjYykpICU+JQogIGZpbHRlcihydF9hY2MgIT0gIm90aGVyIikgJT4lCiAgZ2dwbG90KGFlcyhmYWN0b3IocmF3X2ZpdCwgbGV2ZWxzID0gYygicmF3IiwgIkVaIiwgImhkZG0iKSwgbGFiZWxzPWMoIlJhdyIsICJFWi1kaWZmdXNpb24iLCAiSGllcmFyY2hpY2FsIGRpZmZ1c2lvbiIpKSwgaWNjLCBmaWxsPWZhY3RvcihydF9hY2MsIGxldmVscyA9IGMoInJ0IiwiYWNjdXJhY3kiLCAiZHJpZnQgcmF0ZSIsICJ0aHJlc2hvbGQiLCAibm9uLWRlY2lzaW9uIiksIGxhYmVscz1jKCJSZXNwb25zZSBUaW1lIiwgIkFjY3VyYWN5IiwiRHJpZnQgUmF0ZSIsICJUaHJlc2hvbGQiLCAiTm9uLWRlY2lzaW9uIikpKSkrCiAgZ2VvbV9ib3hwbG90KCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKGNvbnRyYXN0LCBsZXZlbHM9Yygibm9uLWNvbnRyYXN0IiwgImNvbnRyYXN0IiksIGxhYmVscz1jKCJOb24tY29udHJhc3QiLCAiQ29udHJhc3QiKSkpKwogIHlsYWIoIklDQyIpKwogIHhsYWIoIiIpKwogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAnYm90dG9tJykrCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQobmNvbCA9IDIsIGJ5cm93PUYpKQoKbXlsZWdlbmQ8LWdfbGVnZW5kKGRkbV9wb2ludF9wbG90KQoKZ3JvYl9uYW1lIDwtIG5hbWVzKG15bGVnZW5kJGdyb2JzKVsxXQoKI21hbnVhbGx5IGZpeCB0aGUgbGVnZW5kCiNtb3ZlIG5vbi1kZWNpc2lvbiBkb3duCiNrZXkKbXlsZWdlbmQkZ3JvYnNbZ3JvYl9uYW1lXVtbMV1dJGxheW91dFsxMSxjKDE6NCldIDwtIGMoNCw4LDQsOCkKbXlsZWdlbmQkZ3JvYnNbZ3JvYl9uYW1lXVtbMV1dJGxheW91dFsxMixjKDE6NCldIDwtIGMoNCw4LDQsOCkKI3RleHQKbXlsZWdlbmQkZ3JvYnNbZ3JvYl9uYW1lXVtbMV1dJGxheW91dFsxNyxjKDE6NCldIDwtIGMoNCwxMCw0LDEwKQojbW92ZSB0aHJlc2hvbGQgZG93bgoja2V5Cm15bGVnZW5kJGdyb2JzW2dyb2JfbmFtZV1bWzFdXSRsYXlvdXRbOSxjKDE6NCldIDwtIGMoMyw4LDMsOCkKbXlsZWdlbmQkZ3JvYnNbZ3JvYl9uYW1lXVtbMV1dJGxheW91dFsxMCxjKDE6NCldIDwtIGMoMyw4LDMsOCkKI3RleHQKbXlsZWdlbmQkZ3JvYnNbZ3JvYl9uYW1lXVtbMV1dJGxheW91dFsxNixjKDE6NCldIDwtIGMoMywxMCwzLDEwKQojbW92ZSBkcmlmdCByYXRlIHJpZ2h0IGFuZCB1cAoja2V5Cm15bGVnZW5kJGdyb2JzW2dyb2JfbmFtZV1bWzFdXSRsYXlvdXRbNyxjKDE6NCldIDwtIGMoMiw4LDIsOCkKbXlsZWdlbmQkZ3JvYnNbZ3JvYl9uYW1lXVtbMV1dJGxheW91dFs4LGMoMTo0KV0gPC0gYygyLDgsMiw4KQojdGV4dApteWxlZ2VuZCRncm9ic1tncm9iX25hbWVdW1sxXV0kbGF5b3V0WzE1LGMoMTo0KV0gPC0gYygyLDEwLDIsMTApCgpncmlkLmFycmFuZ2UoZGRtX3BvaW50X3Bsb3QgK3RoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpLAogICAgICAgICAgICAgbXlsZWdlbmQsIG5yb3c9MiwgaGVpZ2h0cz1jKDEwLCAxKSkKCgpybShteWxlZ2VuZCwgZGRtX3BvaW50X3Bsb3QpCmBgYAoKUGxvdCBhdmVyYWdlZCBib290c3RyYXBwZWQgcmVsaWFiaWxpdHkgZXN0aW1hdGVzIHBlciBtZWFzdXJlIGNvbXBhcmluZyBERE0gbWVhc3VyZXMgdG8gcmF3IG1lYXN1cmVzIGZhY2V0aW5nIGZvciBjb250cmFzdCBtZWFzdXJlcy4KCmBgYHtyfQpkZG1fYm9vdF9wbG90ID0gYm9vdF9kZiAlPiUKICBncm91cF9ieShkdikgJT4lCiAgc3VtbWFyaXNlKG1lYW5faWNjID0gbWVhbihpY2MpLAogICAgICAgICAgICBydF9hY2MgPSB1bmlxdWUocnRfYWNjKSwKICAgICAgICAgICAgb3ZlcmFsbF9kaWZmZXJlbmNlID0gdW5pcXVlKG92ZXJhbGxfZGlmZmVyZW5jZSksCiAgICAgICAgICAgIHJhd19maXQgPSB1bmlxdWUocmF3X2ZpdCksCiAgICAgICAgICAgIGNvbnRyYXN0ID0gdW5pcXVlKGNvbnRyYXN0KSkgJT4lCiAgbXV0YXRlKHJ0X2FjYyA9IGFzLmNoYXJhY3RlcihydF9hY2MpKSAlPiUKICBmaWx0ZXIocnRfYWNjICE9ICJvdGhlciIpICU+JQogIGdncGxvdChhZXMoZmFjdG9yKHJhd19maXQsIGxldmVscyA9IGMoInJhdyIsICJFWiIsICJoZGRtIiksIGxhYmVscz1jKCJSYXciLCAiRVotZGlmZnVzaW9uIiwgIkhpZXJhcmNoaWNhbCBkaWZmdXNpb24iKSksIG1lYW5faWNjLCBmaWxsPWZhY3RvcihydF9hY2MsIGxldmVscyA9IGMoInJ0IiwiYWNjdXJhY3kiLCAiZHJpZnQgcmF0ZSIsICJ0aHJlc2hvbGQiLCAibm9uLWRlY2lzaW9uIiksIGxhYmVscz1jKCJSZXNwb25zZSBUaW1lIiwgIkFjY3VyYWN5IiwiRHJpZnQgUmF0ZSIsICJUaHJlc2hvbGQiLCAiTm9uLWRlY2lzaW9uIikpKSkrCiAgZ2VvbV9ib3hwbG90KCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKGNvbnRyYXN0LCBsZXZlbHM9Yygibm9uLWNvbnRyYXN0IiwgImNvbnRyYXN0IiksIGxhYmVscz1jKCJOb24tY29udHJhc3QiLCAiQ29udHJhc3QiKSkpKwogIHlsYWIoIklDQyIpKwogIHhsYWIoIiIpKwogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAnYm90dG9tJykrCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQobmNvbCA9IDIsIGJ5cm93PUYpKQoKbXlsZWdlbmQ8LWdfbGVnZW5kKGRkbV9ib290X3Bsb3QpCgpncm9iX25hbWUgPC0gbmFtZXMobXlsZWdlbmQkZ3JvYnMpWzFdCgojbWFudWFsbHkgZml4IHRoZSBsZWdlbmQKI21vdmUgbm9uLWRlY2lzaW9uIGRvd24KI2tleQpteWxlZ2VuZCRncm9ic1tncm9iX25hbWVdW1sxXV0kbGF5b3V0WzExLGMoMTo0KV0gPC0gYyg0LDgsNCw4KQpteWxlZ2VuZCRncm9ic1tncm9iX25hbWVdW1sxXV0kbGF5b3V0WzEyLGMoMTo0KV0gPC0gYyg0LDgsNCw4KQojdGV4dApteWxlZ2VuZCRncm9ic1tncm9iX25hbWVdW1sxXV0kbGF5b3V0WzE3LGMoMTo0KV0gPC0gYyg0LDEwLDQsMTApCiNtb3ZlIHRocmVzaG9sZCBkb3duCiNrZXkKbXlsZWdlbmQkZ3JvYnNbZ3JvYl9uYW1lXVtbMV1dJGxheW91dFs5LGMoMTo0KV0gPC0gYygzLDgsMyw4KQpteWxlZ2VuZCRncm9ic1tncm9iX25hbWVdW1sxXV0kbGF5b3V0WzEwLGMoMTo0KV0gPC0gYygzLDgsMyw4KQojdGV4dApteWxlZ2VuZCRncm9ic1tncm9iX25hbWVdW1sxXV0kbGF5b3V0WzE2LGMoMTo0KV0gPC0gYygzLDEwLDMsMTApCiNtb3ZlIGRyaWZ0IHJhdGUgcmlnaHQgYW5kIHVwCiNrZXkKbXlsZWdlbmQkZ3JvYnNbZ3JvYl9uYW1lXVtbMV1dJGxheW91dFs3LGMoMTo0KV0gPC0gYygyLDgsMiw4KQpteWxlZ2VuZCRncm9ic1tncm9iX25hbWVdW1sxXV0kbGF5b3V0WzgsYygxOjQpXSA8LSBjKDIsOCwyLDgpCiN0ZXh0Cm15bGVnZW5kJGdyb2JzW2dyb2JfbmFtZV1bWzFdXSRsYXlvdXRbMTUsYygxOjQpXSA8LSBjKDIsMTAsMiwxMCkKCmdyaWQuYXJyYW5nZShkZG1fYm9vdF9wbG90ICt0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSwKICAgICAgICAgICAgIG15bGVnZW5kLCBucm93PTIsIGhlaWdodHM9YygxMCwgMSkpCgoKcm0obXlsZWdlbmQsIGRkbV9ib290X3Bsb3QpCmBgYAoKTW9kZWwgdGVzdGluZyBpZiB0aGUgcmVsaWFiaWxpdHkgb2YgcmF3IG1lYXN1cmVzIGRpZmZlcnMgZnJvbSB0aGF0IG9mIGRkbSBlc3RpbWF0ZXMgYW5kIGlmIGNvbnRyYXN0IG1lYXN1cmVzIGRpZmZlciBmcm9tIG5vbi1jb250cmFzdCBtZWFzdXJlcy4KCkNoZWNraW5nIGlmIGJvdGggZml4ZWQgZWZmZWN0cyBvZiByYXcgdnMgZGRtIGFuZCBjb250cmFzdCB2cyBub24tY29udHJhc3QgYXMgd2VsbCBhcyB0aGVpciBpbnRlcmFjdGlvbiBpcyBuZWNlc3NhcnkuCgpDb25jbHVzaW9uOiBNb2RlbCB3aXRoIGZpeGVkIGVmZmVjdCBqdXN0IGZvciBjb250cmFzdCBhbmQgbm90IGZvciByYXcgdnMgZGRtIGFuZCBubyBpbnRlcmFjdGlvbiBpcyB0aGUgYmVzdC4gQnV0IHRvIGFuc3dlciB0aGUgcXVlc3Rpb24gb24gbGFjayBvZiBkaWZmZXJlbmNlIGZvciBkZG0gdnMgcmF3IEknbGwgbG9vayBhdCB0aGUgbW9kZWwgd2l0aCBib3RoIGZpeGVkIGVmZmVjdHMgZm9yIG5vdy4KCmBgYHtyfQptZXIxID0gbG1lcihpY2MgfiBkZG1fcmF3ICsgKDF8ZHYpLCBib290X2RmICU+JSBmaWx0ZXIocnRfYWNjICE9ICJvdGhlciIpKQptZXIxYSA9IGxtZXIoaWNjIH4gY29udHJhc3QgKyAoMXxkdiksIGJvb3RfZGYgJT4lIGZpbHRlcihydF9hY2MgIT0gIm90aGVyIikpCm1lcjIgPSBsbWVyKGljYyB+IGRkbV9yYXcgKyBjb250cmFzdCArICgxfGR2KSwgYm9vdF9kZiAlPiUgZmlsdGVyKHJ0X2FjYyAhPSAib3RoZXIiKSkKbWVyMyA9IGxtZXIoaWNjIH4gZGRtX3JhdyAqIGNvbnRyYXN0ICsgKDF8ZHYpLCBib290X2RmICU+JSBmaWx0ZXIocnRfYWNjICE9ICJvdGhlciIpKQphbm92YShtZXIxLCBtZXIyLCBtZXIzKQphbm92YShtZXIxYSwgbWVyMiwgbWVyMykKYGBgCgpgYGB7cn0Kcm0obWVyMSwgbWVyMywgbWVyMWEpCmBgYAoKUmF3IG1lYXN1cmVzIGRvIG5vdCBzaWduaWZpY2FudGx5IGRpZmZlciBmcm9tIGRkbSBwYXJhbWV0ZXJzIGluIHRoZWlyIHJlbGlhYmlsaXR5IGJ1dCBub24tY29udHJhc3QgbWVhc3VyZXMgYXJlIHNpZ25pZmljYW50bHkgbW9yZSByZWxpYWJsZSBjb21wYXJlZCB0byBjb250cmFzdCBtZWFzdXJlcy4KCmBgYHtyfQpzdW1tYXJ5KG1lcjIpCmBgYAoKIyMgQmVzdCBtZWFzdXJlIGZvciBlYWNoIHRhc2sKCldoYXQgaXMgdGhlIGJlc3QgbWVhc3VyZSBvZiBpbmRpdmlkdWFsIGRpZmZlcmVuY2UgZm9yIGFueSBtZWFzdXJlIHRoYXQgaGFzIGJvdGggcmF3IGFuZCBERE0gcGFyYW1ldGVycz8gCgpFdmVuIHRob3VnaCBvdmVyYWxsIHRoZSBkZG0gcGFyYW1ldGVycyBhcmUgbm90IHNpZ25pZmljYW50bHkgbGVzcyByZWxpYWJsZSB0aGUgbW9zdCByZWxpYWJsZSBtZWFzdXJlIGlzIG1vcmUgZnJlcXVlbnRseSBhIHJhdyBtZWFzdXJlLiBUaGVyZSBhcmUgc29tZSBleGFtcGxlcyBvZiBhbiBFWiBlc3RpbWF0ZSBiZWluZyB0aGUgYmVzdCBmb3IgYSB0YXNrIGFzIHdlbGwuIFJlZ2FyZGxlc3Mgb2YgcmF3IHZzIGRkbSB0aGUgYmVzdCBtZWFzdXJlIGlzIGFsd2F5cyBhIG5vbi1jb250cmFzdCBtZWFzdXJlLiAKCmBgYHtyfQpyZWxfZGYgJT4lCiAgZ3JvdXBfYnkodGFza19ncm91cCkgJT4lCiAgZmlsdGVyKGljYyA9PSBtYXgoaWNjKSkgJT4lCiAgc2VsZWN0KHRhc2tfZ3JvdXAsIGV2ZXJ5dGhpbmcoKSkKYGBgCgojIyBWYXJpYW5jZSBicmVha2Rvd24gbWVhc3VyZSB0eXBlcwoKQ29udmVydGluZyB2YXJpYW5jZSBlc3RpbWF0ZXMgZm9yIGVhY2ggbWVhc3VyZSB0byBwZXJjZW50YWdlIG9mIGFsbCB2YXJpYW5jZSBmb3IgY29tcGFyYWJpbGl0eS4KCmBgYHtyfQpyZWxfZGYgPSByZWxfZGYgJT4lCiAgbXV0YXRlKHZhcl9zdWJzX3BjdCA9ICh2YXJfc3Vicy8odmFyX3N1YnMrdmFyX2luZCt2YXJfcmVzaWQpKSoxMDAsCiAgICAgICAgIHZhcl9pbmRfcGN0ICA9ICh2YXJfaW5kLyh2YXJfc3Vicyt2YXJfaW5kK3Zhcl9yZXNpZCkpKjEwMCwKICAgICAgICAgdmFyX3Jlc2lkX3BjdCA9ICh2YXJfcmVzaWQvKHZhcl9zdWJzK3Zhcl9pbmQrdmFyX3Jlc2lkKSkqMTAwKQoKYm9vdF9kZiA9IGJvb3RfZGYgJT4lCiAgbXV0YXRlKHZhcl9zdWJzX3BjdCA9ICh2YXJfc3Vicy8odmFyX3N1YnMrdmFyX2luZCt2YXJfcmVzaWQpKSoxMDAsCiAgICAgICAgIHZhcl9pbmRfcGN0ICA9ICh2YXJfaW5kLyh2YXJfc3Vicyt2YXJfaW5kK3Zhcl9yZXNpZCkpKjEwMCwKICAgICAgICAgdmFyX3Jlc2lkX3BjdCA9ICh2YXJfcmVzaWQvKHZhcl9zdWJzK3Zhcl9pbmQrdmFyX3Jlc2lkKSkqMTAwKQpgYGAKCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnJlbF9kZiAlPiUKICBmaWx0ZXIocnRfYWNjICE9ICJvdGhlciIpICU+JQogIGdyb3VwX2J5KHJ0X2FjYywgY29udHJhc3QsIHJhd19maXQpICU+JQogIHN1bW1hcmlzZShtZWFuX3Zhcl9zdWJzX3BjdCA9IG1lYW4odmFyX3N1YnNfcGN0KSwKICAgICAgICAgICAgbWVhbl92YXJfaW5kX3BjdCA9IG1lYW4odmFyX2luZF9wY3QpLAogICAgICAgICAgICBtZWFuX3Zhcl9yZXNpZF9wY3QgPSBtZWFuKHZhcl9yZXNpZF9wY3QpLAogICAgICAgICAgICBzZW1fdmFyX3N1YnNfcGN0ID0gc2VtKHZhcl9zdWJzX3BjdCksCiAgICAgICAgICAgIHNlbV92YXJfaW5kX3BjdCA9IHNlbSh2YXJfaW5kX3BjdCksCiAgICAgICAgICAgIHNlbV92YXJfcmVzaWRfcGN0ID0gc2VtKHZhcl9yZXNpZF9wY3QpKSAlPiUKICBnZ3Bsb3QoYWVzKGZhY3RvcihyYXdfZml0LCBsZXZlbHMgPSBjKCJyYXciLCAiRVoiLCAiaGRkbSIpLCBsYWJlbHM9YygiUmF3IiwgIkVaLWRpZmZ1c2lvbiIsICJIaWVyYXJjaGljYWwgZGlmZnVzaW9uIikpLCBtZWFuX3Zhcl9zdWJzX3BjdCwgc2hhcGU9ZmFjdG9yKHJ0X2FjYywgbGV2ZWxzID0gYygicnQiLCJhY2N1cmFjeSIsICJkcmlmdCByYXRlIiwgInRocmVzaG9sZCIsICJub24tZGVjaXNpb24iKSwgbGFiZWxzPWMoIlJlc3BvbnNlIFRpbWUiLCAiQWNjdXJhY3kiLCJEcmlmdCBSYXRlIiwgIlRocmVzaG9sZCIsICJOb24tZGVjaXNpb24iKSkpKSsKICBnZW9tX3BvaW50KHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNzUpLCBzaXplID0gNSkrCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IG1lYW5fdmFyX3N1YnNfcGN0IC0gc2VtX3Zhcl9zdWJzX3BjdCwgeW1heCA9IG1lYW5fdmFyX3N1YnNfcGN0ICsgc2VtX3Zhcl9zdWJzX3BjdCksIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNzUpKSsKICBmYWNldF93cmFwKH5mYWN0b3IoY29udHJhc3QsIGxldmVscz1jKCJub24tY29udHJhc3QiLCAiY29udHJhc3QiKSwgbGFiZWxzPWMoIk5vbi1jb250cmFzdCIsICJDb250cmFzdCIpKSkrCiAgeWxhYigiJSBvZiBiZXR3ZWVuIHN1YmplY3RzIHZhcmlhbmNlIikrCiAgeGxhYigiIikrCiAgdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICdib3R0b20nKQpgYGAKCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnJlbF9kZiAlPiUKICBmaWx0ZXIocnRfYWNjICE9ICJvdGhlciIpICU+JQogIGdyb3VwX2J5KHJ0X2FjYywgY29udHJhc3QsIHJhd19maXQpICU+JQogIHN1bW1hcmlzZShtZWFuX3Zhcl9zdWJzX3BjdCA9IG1lYW4odmFyX3N1YnNfcGN0KSwKICAgICAgICAgICAgbWVhbl92YXJfaW5kX3BjdCA9IG1lYW4odmFyX2luZF9wY3QpLAogICAgICAgICAgICBtZWFuX3Zhcl9yZXNpZF9wY3QgPSBtZWFuKHZhcl9yZXNpZF9wY3QpLAogICAgICAgICAgICBzZW1fdmFyX3N1YnNfcGN0ID0gc2VtKHZhcl9zdWJzX3BjdCksCiAgICAgICAgICAgIHNlbV92YXJfaW5kX3BjdCA9IHNlbSh2YXJfaW5kX3BjdCksCiAgICAgICAgICAgIHNlbV92YXJfcmVzaWRfcGN0ID0gc2VtKHZhcl9yZXNpZF9wY3QpKSAlPiUKICBnZ3Bsb3QoYWVzKGZhY3RvcihyYXdfZml0LCBsZXZlbHMgPSBjKCJyYXciLCAiRVoiLCAiaGRkbSIpLCBsYWJlbHM9YygiUmF3IiwgIkVaLWRpZmZ1c2lvbiIsICJIaWVyYXJjaGljYWwgZGlmZnVzaW9uIikpLCBtZWFuX3Zhcl9yZXNpZF9wY3QsIHNoYXBlPWZhY3RvcihydF9hY2MsIGxldmVscyA9IGMoInJ0IiwiYWNjdXJhY3kiLCAiZHJpZnQgcmF0ZSIsICJ0aHJlc2hvbGQiLCAibm9uLWRlY2lzaW9uIiksIGxhYmVscz1jKCJSZXNwb25zZSBUaW1lIiwgIkFjY3VyYWN5IiwiRHJpZnQgUmF0ZSIsICJUaHJlc2hvbGQiLCAiTm9uLWRlY2lzaW9uIikpKSkrCiAgZ2VvbV9wb2ludChwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjc1KSwgc2l6ZSA9IDUpKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBtZWFuX3Zhcl9yZXNpZF9wY3QgLSBzZW1fdmFyX3Jlc2lkX3BjdCwgeW1heCA9IG1lYW5fdmFyX3Jlc2lkX3BjdCArIHNlbV92YXJfcmVzaWRfcGN0KSwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC43NSkpKwogIGZhY2V0X3dyYXAofmZhY3Rvcihjb250cmFzdCwgbGV2ZWxzPWMoIm5vbi1jb250cmFzdCIsICJjb250cmFzdCIpLCBsYWJlbHM9YygiTm9uLWNvbnRyYXN0IiwgIkNvbnRyYXN0IikpKSsKICB5bGFiKCIlIG9mIHJlc2lkdWFsIHZhcmlhbmNlIikrCiAgeGxhYigiIikrCiAgdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICdib3R0b20nKQpgYGAKCk1vZGVsIHRlc3RpbmcgaWYgdGhlIHBlcmNlbnRhZ2Ugb2YgYmV0d2VlbiBzdWJqZWN0cyB2YXJpYW5jZSBvZiByYXcgbWVhc3VyZXMgZGlmZmVycyBmcm9tIHRoYXQgb2YgZGRtIGVzdGltYXRlcyBhbmQgaWYgY29udHJhc3QgbWVhc3VyZXMgZGlmZmVyIGZyb20gbm9uLWNvbnRyYXN0IG1lYXN1cmVzLgoKQ2hlY2tpbmcgaWYgYm90aCBmaXhlZCBlZmZlY3RzIG9mIHJhdyB2cyBkZG0gYW5kIGNvbnRyYXN0IHZzIG5vbi1jb250cmFzdCBhcyB3ZWxsIGFzIHRoZWlyIGludGVyYWN0aW9uIGlzIG5lY2Vzc2FyeS4KCkNvbmNsdXNpb246IE1vZGVsIHdpdGggZml4ZWQgZWZmZWN0cyBmb3IgYm90aCBpcyBiZXN0LgoKYGBge3J9Cm1lcjEgPSBsbWVyKHZhcl9zdWJzX3BjdCB+IGRkbV9yYXcgKyAoMXxkdiksIGJvb3RfZGYgJT4lIGZpbHRlcihydF9hY2MgIT0gIm90aGVyIikpCm1lcjFhID0gbG1lcih2YXJfc3Vic19wY3QgfiBjb250cmFzdCArICgxfGR2KSwgYm9vdF9kZiAlPiUgZmlsdGVyKHJ0X2FjYyAhPSAib3RoZXIiKSkKbWVyMiA9IGxtZXIodmFyX3N1YnNfcGN0IH4gZGRtX3JhdyArIGNvbnRyYXN0ICsgKDF8ZHYpLCBib290X2RmICU+JSBmaWx0ZXIocnRfYWNjICE9ICJvdGhlciIpKQptZXIzID0gbG1lcih2YXJfc3Vic19wY3QgfiBkZG1fcmF3ICogY29udHJhc3QgKyAoMXxkdiksIGJvb3RfZGYgJT4lIGZpbHRlcihydF9hY2MgIT0gIm90aGVyIikpCmFub3ZhKG1lcjEsIG1lcjIsIG1lcjMpCmFub3ZhKG1lcjFhLCBtZXIyLCBtZXIzKQpgYGAKCmBgYHtyfQpybShtZXIxLCBtZXIxYSwgbWVyMykKYGBgCgpSYXcgYW5kIG5vbi1jb250cmFzdCBtZWFzdXJlcyBoYXZlIGhpZ2hlciBiZXR3ZWVuIHN1YmplY3RzIHZhcmlhbmNlIChpZSBhcmUgYmV0dGVyIGluZGl2aWR1YWwgZGlmZmVyZW5jZSBtZWFzdXJlcykKCmBgYHtyfQpzdW1tYXJ5KG1lcjIpCmBgYAoKTW9kZWwgdGVzdGluZyBpZiB0aGUgcGVyY2VudGFnZSBvZiByZXNpZHVhbCB2YXJpYW5jZSBvZiByYXcgbWVhc3VyZXMgZGlmZmVycyBmcm9tIHRoYXQgb2YgZGRtIGVzdGltYXRlcyBhbmQgaWYgY29udHJhc3QgbWVhc3VyZXMgZGlmZmVyIGZyb20gbm9uLWNvbnRyYXN0IG1lYXN1cmVzLgoKQ2hlY2tpbmcgaWYgYm90aCBmaXhlZCBlZmZlY3RzIG9mIHJhdyB2cyBkZG0gYW5kIGNvbnRyYXN0IHZzIG5vbi1jb250cmFzdCBhcyB3ZWxsIGFzIHRoZWlyIGludGVyYWN0aW9uIGlzIG5lY2Vzc2FyeS4KCkNvbmNsdXNpb246IE1vZGVsIHdpdGggZml4ZWQgZWZmZWN0IGp1c3QgZm9yIGNvbnRyYXN0IGlzIGJlc3QuIEFuZCBwbG90IGFib3ZlIGFscmVhZHkgc2hvd3MgdGhhdCBjb250cmFzdCBtZWFzdXJlcyBoYXZlIGhpZ2hlciByZXNpZHVhbCB2YXJpYW5jZS4KCmBgYHtyfQptZXIxID0gbG1lcih2YXJfcmVzaWRfcGN0IH4gZGRtX3JhdyArICgxfGR2KSwgYm9vdF9kZiAlPiUgZmlsdGVyKHJ0X2FjYyAhPSAib3RoZXIiKSkKbWVyMWEgPSBsbWVyKHZhcl9yZXNpZF9wY3QgfiBjb250cmFzdCArICgxfGR2KSwgYm9vdF9kZiAlPiUgZmlsdGVyKHJ0X2FjYyAhPSAib3RoZXIiKSkKbWVyMiA9IGxtZXIodmFyX3Jlc2lkX3BjdCB+IGRkbV9yYXcgKyBjb250cmFzdCArICgxfGR2KSwgYm9vdF9kZiAlPiUgZmlsdGVyKHJ0X2FjYyAhPSAib3RoZXIiKSkKbWVyMyA9IGxtZXIodmFyX3Jlc2lkX3BjdCB+IGRkbV9yYXcgKiBjb250cmFzdCArICgxfGR2KSwgYm9vdF9kZiAlPiUgZmlsdGVyKHJ0X2FjYyAhPSAib3RoZXIiKSkKYW5vdmEobWVyMSwgbWVyMiwgbWVyMykKYW5vdmEobWVyMWEsIG1lcjIsIG1lcjMpCmBgYAoKYGBge3J9CnJtKG1lcjEsIG1lcjFhLCBtZXIyLCBtZXIzKQpgYGAKCiMjIFNhbXBsZSBzaXplIGVmZmVjdHMgb24gcmVsaWFiaWxpdHkKCkRpZmZlcmVuY2VzIGluIERETSBwYXJhbWV0ZXIgcmVsaWFiaWxpdHkgZm9yIHQxIGRhdGEgdXNpbmcgZWl0aGVyIG49NTUyIG9yIG49MTUwIHdlcmUgcmVwb3J0ZWQgYWJvdmUgdW5kZXIgW1QxIEhERE0gcGFyYW1ldGVyc10oaHR0cHM6Ly96ZW5rYXZpLmdpdGh1Yi5pby9TUk9fRERNX0FuYWx5c2VzL291dHB1dC9yZXBvcnRzL1NST19ERE1fQW5hbHlzZXMubmIuaHRtbCN0MV9oZGRtX3BhcmFtZXRlcnMpLiBObyBtZWFuaW5nZnVsIGRpZmZlcmVuY2VzIGV4aXN0IGJldHdlZW4gdGhlc2UgdHdvIHNhbXBsZSBzaXplcy4KCkJ1dCBldmVuIDE1MCBpcyBhIGxhcmdlIHNhbXBsZSBzaXplIGZvciBwc3ljaG9sb2dpY2FsIHN0dWRpZXMsIGVzcGVjaWFsbHkgZm9yY2VkIGNob2ljZSByZWFjdGlvbiB0aW1lIHRhc2tzIHRoYXQgYXJlIGluY2x1ZGVkIGluIHRoaXMgcmVwb3J0LiBIZXJlIHdlIGxvb2sgYXQgaG93IHRoZSByZWxpYWJpbGl0eSBmb3IgcmF3IGFuZCBkZG0gbWVhc3VyZXMgY2hhbmdlIGZvciBzYW1wbGUgc2l6ZXMgdGhhdCBhcmUgbW9yZSBjb21tb24gaW4gc3R1ZGllcyB1c2luZyB0aGVzZSB0YXNrcyAoMjUsIDUwLCA3NSwgMTAwLCAxMjUsIDE1MCkKCk5vdGU6IE5vdCByZWZpdHRpbmcgSERETSdzIGZvciBlYWNoIG9mIHRoZXNlIHNhbXBsZSBzaXplcyBzaW5jZSBhLiB0aGVyZSB3ZXJlIG5vIGRpZmZlcmVuY2VzIGluIHBhcmFtZXRlciBzdGFiaWxpdHkgZm9yIG49MTUwIHZzIDU1MiBhbmQgYi4gYSBtb3JlIGNvbXByZWhlbnNpdmUgY29tcGFyaXNvbiB1c2luZyBub24taGllcmFyY2hpY2FsIGVzdGltYXRlcyBhbmQgbW9kZWwgZml0IGluZGljZXMgd2lsbCBmb2xsb3cuICpbcmV2aXNpdCB0aGlzIC0gMTUwIGFuZCA1NTIgbWlnaHQgYmUgdG9vIGxhcmdlIHRvIGxlYWQgdG8gY2hhbmdlcyBpbiBwYXJhbWV0ZXIgZXN0aW1hdGVzIGJ1dCBzbWFsbGVyIHNhbXBsZXMgdGhhdCBhcmUgbW9yZSBjb21tb24gaW4gcHN5Y2ggc3R1ZGllcyBtaWdodCBzd2F5IGVzdGltYXRlcyBtb3JlXSoKCmBgYHtyfQpyZWxfZGZfc2FtcGxlX3NpemUgPSByZWFkLmNzdihnemZpbGUocGFzdGUwKGlucHV0X3BhdGgsICdyZWxfZGZfc2FtcGxlX3NpemUuY3N2Lmd6JykpKQoKI0NoZWNrIGlmIGFsbCB2YXJzIGFyZSB0aGVyZQojIG51bWVyaWNfY29sc1t3aGljaChudW1lcmljX2NvbHMgJWluJSB1bmlxdWUocmVsX2RmX3NhbXBsZV9zaXplJGR2KSA9PSBGQUxTRSldCgpyZWxfZGZfc2FtcGxlX3NpemUgPSByZWxfZGZfc2FtcGxlX3NpemUgJT4lCiAgbGVmdF9qb2luKG1lYXN1cmVfbGFiZWxzWyxjKCJkdiIsICJ0YXNrX2dyb3VwIiwib3ZlcmFsbF9kaWZmZXJlbmNlIiwicmF3X2ZpdCIsInJ0X2FjYyIpXSwgYnkgPSAiZHYiKSAlPiUKICBtdXRhdGUoZGRtX3JhdyA9IGlmZWxzZShyYXdfZml0ID09ICJyYXciLCAicmF3IiwgImRkbSIpLAogICAgICAgICBjb250cmFzdCA9IGlmZWxzZShvdmVyYWxsX2RpZmZlcmVuY2UgPT0gImRpZmZlcmVuY2UiLCAiY29udHJhc3QiLCAibm9uLWNvbnRyYXN0IiksCiAgICAgICAgIGNvbnRyYXN0ID0gZmFjdG9yKGNvbnRyYXN0LCBsZXZlbHM9Yygibm9uLWNvbnRyYXN0IiwgImNvbnRyYXN0IikpLAogICAgICAgICB2YXJfc3Vic19wY3QgPSAodmFyX3N1YnMvKHZhcl9zdWJzK3Zhcl9pbmQrdmFyX3Jlc2lkKSkqMTAwLAogICAgICAgICB2YXJfaW5kX3BjdCAgPSAodmFyX2luZC8odmFyX3N1YnMrdmFyX2luZCt2YXJfcmVzaWQpKSoxMDAsCiAgICAgICAgIHZhcl9yZXNpZF9wY3QgPSAodmFyX3Jlc2lkLyh2YXJfc3Vicyt2YXJfaW5kK3Zhcl9yZXNpZCkpKjEwMCkKCnJlbF9kZl9zYW1wbGVfc2l6ZV9zdW1tYXJ5ID0gcmVsX2RmX3NhbXBsZV9zaXplICU+JSAKICBncm91cF9ieShkdiwgc2FtcGxlX3NpemUsIGRkbV9yYXcsIGNvbnRyYXN0KSAlPiUKICBzdW1tYXJpc2UobWVhbl9pY2MgPSBtZWFuKGljYyksCiAgICAgICAgICAgIHNlbV9pY2MgPSBzZW0oaWNjKSwgCiAgICAgICAgICAgIG1lYW5fdmFyX3N1YnNfcGN0ID0gbWVhbih2YXJfc3Vic19wY3QpLAogICAgICAgICAgICBzZW1fdmFyX3N1YnNfcGN0ID0gc2VtKHZhcl9zdWJzX3BjdCksCiAgICAgICAgICAgIG1lYW5fdmFyX2luZF9wY3QgPSBtZWFuKHZhcl9pbmRfcGN0KSwKICAgICAgICAgICAgc2VtX3Zhcl9pbmRfcGN0ID0gc2VtKHZhcl9pbmRfcGN0KSwKICAgICAgICAgICAgbWVhbl92YXJfcmVzaWRfcGN0ID0gbWVhbih2YXJfcmVzaWRfcGN0KSwKICAgICAgICAgICAgc2VtX3Zhcl9yZXNpZF9wY3QgPSBzZW0odmFyX3Jlc2lkX3BjdCkpCgp0bXAgPSByZWxfZGZfc2FtcGxlX3NpemUgJT4lIAogIGdyb3VwX2J5KHNhbXBsZV9zaXplKSAlPiUKICBzdW1tYXJpc2UobWVhbl9pY2MgPSBtZWFuKGljYyksCiAgICAgICAgICAgIHNlbV9pY2MgPSBzZW0oaWNjKSwgCiAgICAgICAgICAgIG1lYW5fdmFyX3N1YnNfcGN0ID0gbWVhbih2YXJfc3Vic19wY3QpLAogICAgICAgICAgICBzZW1fdmFyX3N1YnNfcGN0ID0gc2VtKHZhcl9zdWJzX3BjdCksCiAgICAgICAgICAgIG1lYW5fdmFyX2luZF9wY3QgPSBtZWFuKHZhcl9pbmRfcGN0KSwKICAgICAgICAgICAgc2VtX3Zhcl9pbmRfcGN0ID0gc2VtKHZhcl9pbmRfcGN0KSwKICAgICAgICAgICAgbWVhbl92YXJfcmVzaWRfcGN0ID0gbWVhbih2YXJfcmVzaWRfcGN0KSwKICAgICAgICAgICAgc2VtX3Zhcl9yZXNpZF9wY3QgPSBzZW0odmFyX3Jlc2lkX3BjdCkpCmBgYAoKRG9lcyB0aGUgbWVhbiByZWxpYWJpbGl0eSBjaGFuZ2Ugd2l0aCBzYW1wbGUgc2l6ZT8KClllcy4gVGhlIGxhcmdlciB0aGUgc2FtcGxlIHNpemUgdGhlIG1vcmUgcmVsaWFibGUgaXMgYSBnaXZlbiBtZWFzdXJlIG9uIGF2ZXJhZ2UuIFRoZSBsYXJnZXN0IGluY3JlYXNlIGluIHJlbGlhYmlsaXR5IGlzIHdoZW4gc2hpZnRpbmcgZnJvbSAyNSB0byA1MCBzdWJqZWN0cy4gVGhpcyBpcyBpbXBvcnRhbnQgYmVjYXVzZSBtYW55IHN0dWRpZXMgdXNpbmcgdGhlc2UgbWVhc3VyZXMgaGF2ZSBzYW1wbGUgc2l6ZXMgPDUwIHBlciBncm91cC4KCmBgYHtyfQpyZWxfZGZfc2FtcGxlX3NpemVfc3VtbWFyeSAlPiUKICBnZ3Bsb3QoYWVzKHNhbXBsZV9zaXplLCBtZWFuX2ljYykpKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBkdiksIGFscGhhID0gMC4xKSsKICBnZW9tX2xpbmUoZGF0YSA9IHRtcCxhZXMoc2FtcGxlX3NpemUsbWVhbl9pY2MpLCBjb2xvcj0icmVkIikrCiAgZ2VvbV9wb2ludChkYXRhID0gdG1wLGFlcyhzYW1wbGVfc2l6ZSxtZWFuX2ljYyksIGNvbG9yPSJyZWQiKSsKICBnZW9tX2Vycm9yYmFyKGRhdGEgPSB0bXAsYWVzKHltaW49bWVhbl9pY2Mtc2VtX2ljYywgeW1heCA9IG1lYW5faWNjK3NlbV9pY2MpLCBjb2xvcj0icmVkIiwgd2lkdGggPSAwLjEpKwogIHlsYWIoIk1lYW4gcmVsaWFiaWxpdHkgb2YgMTAwIHNhbXBsZXMgb2Ygc2l6ZSBuIikrCiAgeGxhYigiU2FtcGxlIHNpemUiKQpgYGAKCmBgYHtyfQpzdW1tYXJ5KGxtZXIoaWNjIH4gZmFjdG9yKHNhbXBsZV9zaXplKSArICgxfGR2KSArICgxfGl0ZXJhdGlvbiksIHJlbF9kZl9zYW1wbGVfc2l6ZSkpCmBgYAoKRG9lcyB0aGUgY2hhbmdlIGluIHJlbGlhYmlsaWl0eSB3aXRoIHNhbXBsZSBzaXplIHZhcnkgYnkgdmFyaWFibGUgdHlwZT8KClRoZSBjaGFuZ2VzIGRvIG5vdCBkaWZmZXIgYnkgcmF3IHZzLiBkZG0gbWVhc3VyZXMuIEl0IGRvZXMgZGlmZmVyIGJ5IHdoZXRoZXIgdGhlIG1lYXN1cmUgaXMgYSBjb250cmFzdCBtZWFzdXJlOiBGb3IgY29udHJhc3QgbWVhc3VyZXMgYWxsIGluY3JlYXNlcyBpbiByZWxpYWJpbGl0eSB3aXRoIHNhbXBsZSBzaXplIGFyZSBsYXJnZXIgdGhhbiB0aGUgaW5jcmVhc2VzIGZvciBub24tY29udHJhc3QgbWVhc3VyZXMuIFRoaXMgaW1wbGllcyB0aGF0IGxhcmdlciBzYW1wbGUgc2l6ZXMgYXJlIGV2ZW4gbW9yZSBjcnVjaWFsIGZvciBzdHVkaWVzIHVzaW5nIGNvbnRyYXN0IG1lYXN1cmVzIGFzIHRyYWl0LWxldmVsIG1lYXN1cmVzLgoKYGBge3J9CnRtcCA9IHJlbF9kZl9zYW1wbGVfc2l6ZSAlPiUgCiAgZ3JvdXBfYnkoc2FtcGxlX3NpemUsIGRkbV9yYXcsIGNvbnRyYXN0KSAlPiUKICBzdW1tYXJpc2UobWVhbl9pY2MgPSBtZWFuKGljYyksCiAgICAgICAgICAgIHNlbV9pY2MgPSBzZW0oaWNjKSwgCiAgICAgICAgICAgIG1lYW5fdmFyX3N1YnNfcGN0ID0gbWVhbih2YXJfc3Vic19wY3QpLAogICAgICAgICAgICBzZW1fdmFyX3N1YnNfcGN0ID0gc2VtKHZhcl9zdWJzX3BjdCksCiAgICAgICAgICAgIG1lYW5fdmFyX2luZF9wY3QgPSBtZWFuKHZhcl9pbmRfcGN0KSwKICAgICAgICAgICAgc2VtX3Zhcl9pbmRfcGN0ID0gc2VtKHZhcl9pbmRfcGN0KSwKICAgICAgICAgICAgbWVhbl92YXJfcmVzaWRfcGN0ID0gbWVhbih2YXJfcmVzaWRfcGN0KSwKICAgICAgICAgICAgc2VtX3Zhcl9yZXNpZF9wY3QgPSBzZW0odmFyX3Jlc2lkX3BjdCkpCmBgYAoKYGBge3J9CnJlbF9kZl9zYW1wbGVfc2l6ZV9zdW1tYXJ5ICU+JQogIGdncGxvdChhZXMoc2FtcGxlX3NpemUsIG1lYW5faWNjKSkrCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IGR2LCBjb2xvcj1kZG1fcmF3KSwgYWxwaGEgPSAwLjEpKwogIGdlb21fbGluZShkYXRhID0gdG1wLCBhZXMoc2FtcGxlX3NpemUsbWVhbl9pY2MsIGNvbG9yPWRkbV9yYXcpKSsKICBnZW9tX3BvaW50KGRhdGEgPSB0bXAsIGFlcyhzYW1wbGVfc2l6ZSxtZWFuX2ljYywgY29sb3I9ZGRtX3JhdykpKwogIGdlb21fZXJyb3JiYXIoZGF0YSA9IHRtcCxhZXMoeW1pbj1tZWFuX2ljYy1zZW1faWNjLCB5bWF4ID0gbWVhbl9pY2Mrc2VtX2ljYyksIGNvbG9yPSJyZWQiLCB3aWR0aCA9IDAuMSkrCiAgZmFjZXRfd3JhcCh+Y29udHJhc3QpKwogIHlsYWIoIk1lYW4gcmVsaWFiaWxpdHkgb2YgMTAwIHNhbXBsZXMgb2Ygc2l6ZSBuIikrCiAgeGxhYigiU2FtcGxlIHNpemUiKSsKICB0aGVtZShsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpCmBgYAoKYGBge3J9CnN1bW1hcnkobG1lcihpY2MgfiBmYWN0b3Ioc2FtcGxlX3NpemUpICogY29udHJhc3QgKyAoMXxkdikgKyAoMXxpdGVyYXRpb24pLCByZWxfZGZfc2FtcGxlX3NpemUpKQpgYGAKCkRvZXMgdmFyaWFiaWxpdHkgb2YgcmVsaWFiaWxpdHkgY2hhbmdlIHdpdGggc2FtcGxlIHNpemU/CgpZZXMuIFZhcmlhYmlsaXR5IG9mIHJlbGlhYmlsaXR5IGRlY3JlYXNlcyB3aXRoIHNhbXBsZSBzaXplLiBJdCBkb2VzIHNvIG1vcmUgc3Ryb25nbHkgZm9yIGNvbnRyYXN0IG1lYXN1cmVzLgoKYGBge3J9CnJlbF9kZl9zYW1wbGVfc2l6ZV9zdW1tYXJ5ICU+JQogIGdncGxvdChhZXMoc2FtcGxlX3NpemUsIHNlbV9pY2MpKSsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gZHYsIGNvbG9yPWRkbV9yYXcpLCBhbHBoYSA9IDAuMSkrCiAgZ2VvbV9saW5lKGRhdGEgPSB0bXAsIGFlcyhzYW1wbGVfc2l6ZSxzZW1faWNjLCBjb2xvcj1kZG1fcmF3KSkrCiAgZ2VvbV9wb2ludChkYXRhID0gdG1wLCBhZXMoc2FtcGxlX3NpemUsc2VtX2ljYywgY29sb3I9ZGRtX3JhdykpKwogIGZhY2V0X3dyYXAofmNvbnRyYXN0KSsKICB5bGFiKCJTdGFuZGFyZCBlcnJvciBvZiBtZWFuIG9mIHJlbGlhYmlsaXR5IFxuIG9mIDEwMCBzYW1wbGVzIG9mIHNpemUgbiIpKwogIHhsYWIoIlNhbXBsZSBzaXplIikrCiAgdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKQpgYGAKCmBgYHtyfQpzdW1tYXJ5KGxtZXIoc2VtX2ljYyB+IGZhY3RvcihzYW1wbGVfc2l6ZSkgKiBjb250cmFzdCArICgxfGR2KSwgcmVsX2RmX3NhbXBsZV9zaXplX3N1bW1hcnkpKQpgYGAKCkRvZXMgYmV0d2VlbiBzdWJqZWN0cyB2YXJpYW5jZSBjaGFuZ2Ugd2l0aCBzYW1wbGUgc2l6ZT8KClllcy4gQmV0d2VlbiBzdWJqZWN0cyB2YXJpYW5jZSBkZWNyZWFzZXMgd2l0aCBzYW1wbGUgc2l6ZS4gVGhpcyBpcyBtb3JlIHByb25vdW5jZWQgZm9yIG5vbi1jb250cmFzdCBtZWFzdXJlcy4KClRoaXMgZ29lcyBhZ2FpbnN0IG15IGludHVpdGlvbnMuIExvb2tpbmcgYXQgdGhlIGNoYW5nZSBpbiBiZXR3ZWVuIHN1YmplY3RzIHBlcmNlbnRhZ2Ugb2YgaW5kaXZpZHVhbCBtZWFzdXJlcycgdGhlcmUgc2VlbXMgdG8gYmUgYSBsb3Qgb2YgaW50ZXItbWVhc3VyZSB2YXJpYW5jZSAobW9yZSBwcm9ub3VuY2VkIGJlbG93IGZvciB3aXRoaW4gc3ViamVjdCB2YXJpYW5jZSkuIEknbSBub3Qgc3VyZSBpZiB0aGVyZSBpcyBzb21ldGhpbmcgaW4gY29tbW9uIGZvciB0aGUgbWVhc3VyZXMgdGhhdCBzaG93IGluY3JlYXNpbmcgYmV0d2VlbiBzdWJqZWN0cyB2YXJpYWJpbGl0eSB3aXRoIHNhbXBsZSBzaXplIGFuZCB0aGF0IHNlcGFyYXRlcyB0aGVtIGZyb20gdGhvc2UgdGhhdCBzaG93IGRlY3JlYXNpbmcgYmV0d2VlbiBzdWJqZWN0cyB2YXJpYWJpbGl0eSB3aXRoIHNhbXBsZSBzaXplICh0aGUgc2xpZ2h0IG1ham9yaXR5KS4KCmBgYHtyfQpyZWxfZGZfc2FtcGxlX3NpemVfc3VtbWFyeSAlPiUKICBnZ3Bsb3QoYWVzKHNhbXBsZV9zaXplLCBtZWFuX3Zhcl9zdWJzX3BjdCkpKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBkdiwgY29sb3I9ZGRtX3JhdyksIGFscGhhID0gMC4xKSsKICBnZW9tX2xpbmUoZGF0YSA9IHRtcCwgYWVzKHNhbXBsZV9zaXplLG1lYW5fdmFyX3N1YnNfcGN0LCBjb2xvcj1kZG1fcmF3KSkrCiAgZ2VvbV9wb2ludChkYXRhID0gdG1wLCBhZXMoc2FtcGxlX3NpemUsbWVhbl92YXJfc3Vic19wY3QsIGNvbG9yPWRkbV9yYXcpKSsKICBmYWNldF93cmFwKH5jb250cmFzdCkrCiAgeWxhYigiTWVhbiBwZXJjZW50YWdlIG9mIFxuIGJldHdlZW4gc3ViamVjdHMgdmFyaWFuY2UgXG4gb2YgMTAwIHNhbXBsZXMgb2Ygc2l6ZSBuIikrCiAgeGxhYigiU2FtcGxlIHNpemUiKSsKICB0aGVtZShsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpCmBgYAoKYGBge3J9CnN1bW1hcnkobG1lcih2YXJfc3Vic19wY3QgfiBmYWN0b3Ioc2FtcGxlX3NpemUpICogY29udHJhc3QgKyAoMXxkdikgKyAoMXxpdGVyYXRpb24pLCByZWxfZGZfc2FtcGxlX3NpemUpKQpgYGAKCkRvZXMgd2l0aGluIHN1YmplY3RzIHZhcmlhbmNlIGNoYW5nZSB3aXRoIHNhbXBsZSBzaXplPwoKWWVzLiBUaGlzIGFnYWluIGdvZXMgYWdhaW5zdCBteSBpbnR1aXRpb24gYnV0IGhlcmUgdGhlIGludGVyLW1lYXVzcmUgZGlmZmVyZW5jZXMgYXJlIGV2ZW4gbW9yZSBwcm9ub3VuY2VkLiBUaGVyZSBhcHBlYXJzIHRvIGJlIHNvbWUgbWVhc3VyZXMgZm9yIHdoaWNoIHRoZSBjaGFuZ2UgaW4gdHdvIG1lYXN1cmVtZW50cyBhdCBkaWZmZXJlbnQgdGltZSBwb2ludHMgaXMgbGFyZ2VyIHRoZSBtb3JlIHN1YmplY3RzIGFyZSB0ZXN0ZWQgYW5kIHRob3NlIHRoYXQgc2hvdyBhIHNtYWxsZXIgZGVjcmVhc2UgaW4gd2l0aGluIHN1YmplY3QgdmFyaWFuY2Ugd2l0aCBsYXJnZXIgc2FtcGxlIHNpemVzLiBJIHN0aWxsIGRvbid0IGtub3cgaWYgdGhlc2UgdHdvIHR5cGVzIG9mIG1lYXN1cmVzIGhhdmUgYW55dGhpbmcgdGhhdCBkaXN0aW5ndWlzaGVzIHRoZW0uCgpgYGB7cn0KcmVsX2RmX3NhbXBsZV9zaXplX3N1bW1hcnkgJT4lCiAgZ2dwbG90KGFlcyhzYW1wbGVfc2l6ZSwgbWVhbl92YXJfaW5kX3BjdCkpKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBkdiwgY29sb3I9ZGRtX3JhdyksIGFscGhhID0gMC4xKSsKICBnZW9tX2xpbmUoZGF0YSA9IHRtcCwgYWVzKHNhbXBsZV9zaXplLG1lYW5fdmFyX2luZF9wY3QsIGNvbG9yPWRkbV9yYXcpKSsKICBnZW9tX3BvaW50KGRhdGEgPSB0bXAsIGFlcyhzYW1wbGVfc2l6ZSxtZWFuX3Zhcl9pbmRfcGN0LCBjb2xvcj1kZG1fcmF3KSkrCiAgZmFjZXRfd3JhcCh+Y29udHJhc3QpKwogIHlsYWIoIk1lYW4gcGVyY2VudGFnZSBvZiBcbiB3aXRoaW4gc3ViamVjdHMgdmFyaWFuY2UgXG4gb2YgMTAwIHNhbXBsZXMgb2Ygc2l6ZSBuIikrCiAgeGxhYigiU2FtcGxlIHNpemUiKSsKICB0aGVtZShsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpCmBgYAoKYGBge3J9CnN1bW1hcnkobG1lcih2YXJfaW5kX3BjdCB+IGZhY3RvcihzYW1wbGVfc2l6ZSkgKiBjb250cmFzdCArICgxfGR2KSArICgxfGl0ZXJhdGlvbiksIHJlbF9kZl9zYW1wbGVfc2l6ZSkpCmBgYAoKRG9lcyByZXNpZHVhbCB2YXJpYW5jZSBjaGFuZ2Ugd2l0aCBzYW1wbGUgc2l6ZT8KCmBgYHtyfQpyZWxfZGZfc2FtcGxlX3NpemVfc3VtbWFyeSAlPiUKICBnZ3Bsb3QoYWVzKHNhbXBsZV9zaXplLCBtZWFuX3Zhcl9yZXNpZF9wY3QpKSsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gZHYsIGNvbG9yPWRkbV9yYXcpLCBhbHBoYSA9IDAuMSkrCiAgZ2VvbV9saW5lKGRhdGEgPSB0bXAsIGFlcyhzYW1wbGVfc2l6ZSxtZWFuX3Zhcl9yZXNpZF9wY3QsIGNvbG9yPWRkbV9yYXcpKSsKICBnZW9tX3BvaW50KGRhdGEgPSB0bXAsIGFlcyhzYW1wbGVfc2l6ZSxtZWFuX3Zhcl9yZXNpZF9wY3QsIGNvbG9yPWRkbV9yYXcpKSsKICBmYWNldF93cmFwKH5jb250cmFzdCkrCiAgeWxhYigiTWVhbiBwZXJjZW50YWdlIG9mIHJlc2lkdWFsIHZhcmlhbmNlIFxuIG9mIDEwMCBzYW1wbGVzIG9mIHNpemUgbiIpKwogIHhsYWIoIlNhbXBsZSBzaXplIikrCiAgdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKQpgYGAKCmBgYHtyfQpzdW1tYXJ5KGxtZXIodmFyX3Jlc2lkX3BjdCB+IGZhY3RvcihzYW1wbGVfc2l6ZSkgKiBjb250cmFzdCArICgxfGR2KSArICgxfGl0ZXJhdGlvbiksIHJlbF9kZl9zYW1wbGVfc2l6ZSkpCmBgYAoKIyMgSGllcmFyY2hpY2FsIGVzdGltYXRpb24gY29uc2VxdWVuY2VzCgotIElzIHRoZSBIIGluIEhERE0gaW1wb3J0YW50PyAoaCB2cyBmbGF0KQotLSBDaGFuZ2UgaW4gcGFyYW1ldGVyIHZhbHVlPwotLSBDaGFuZ2UgaW4gcGFyYW1ldGVyIHJlbGlhYmlsaXR5PwoKIyMgQ2x1c3RlcmluZwotLSBEbyBERE0gcGFyYW1ldGVycyBjYXB0dXJlIHNpbWlsYXIgcHJvY2Vzc2VzIGFzIHRoZSByYXcgbWVhc3VyZXMgaW4gYSBnaXZlbiB0YXNrIG9yIGRvIHRoZXkgY2FwdHVyZSBwcm9jZXNzZXMgdGhhdCBhcmUgbW9yZSBzaW1pbGFyIGFjcm9zcyB0YXNrcz8KLS0gQXJlIHRoZXNlIGNsdXN0ZXJzIG1vcmUgcmVsaWFibGUgdGhhbiB1c2luZyBlaXRoZXIgdGhlIHJhdyBvciB0aGUgRERNIG1lYXN1cmVzIGFsb25lPwoKIyMgUHJlZGljdGlvbgotLSBEbyByYXcgb3IgRERNIG1lYXN1cmVzIChvciBmYWN0b3Igc2NvcmVzKSBwcmVkaWN0IHJlYWwgd29ybGQgb3V0Y29tZXMgYmV0dGVyPwoKIyMgVG8gRG8KClByb2YuIERvbWluZ3VlIHJlY29tbWVuZGVkIHJlYWRpbmdzOgpmaWxlOi8vL1VzZXJzL3pleW5lcGVua2F2aS9Eb3dubG9hZHMvMTAuMTAwNyUyNTJGczExMzM2LTAwNi0xNDc4LXoucGRmCkEgSElFUkFSQ0hJQ0FMIEZSQU1FV09SSyBGT1IgTU9ERUxJTkcgU1BFRUQgQU5EIEFDQ1VSQUNZCk9OIFRFU1QgSVRFTVMKCmZpbGU6Ly8vVXNlcnMvemV5bmVwZW5rYXZpL0Rvd25sb2Fkcy92NjZpMDQucGRmCkZpdHRpbmcgRGlmZnVzaW9uIEl0ZW0gUmVzcG9uc2UgVGhlb3J5IE1vZGVscyBmb3IKUmVzcG9uc2VzIGFuZCBSZXNwb25zZSBUaW1lcyBVc2luZyB0aGUgUgpQYWNrYWdlIGRpZmZJUlQ=